How to Fix Fedora Login Loop (Keeps Returning to Login Screen)

Fix the Fedora login loop by booting into rescue mode and resetting your home directory permissions.

The screen flashes and drops you back to the login prompt

You type your password. The background fades. The cursor spins for two seconds. Then you are staring at the login screen again. No desktop, no error message, just the prompt waiting for you to try again. This happens after a major update, a sudden power loss, or a failed package transaction. The system is not broken. Your user environment is.

What is actually happening

The display manager, usually GDM on Fedora, handles authentication and session handoff. When you enter your credentials, GDM verifies them against the system database. If they match, GDM launches your desktop environment session manager. The session manager immediately reads configuration files, environment variables, and user-specific settings from your home directory. If it encounters a file it cannot read, a directory with wrong ownership, or a corrupted configuration, it aborts the session for safety. GDM catches the abort and returns you to the login screen. This is a safety valve, not a crash.

The root cause is almost always file permission drift, ownership corruption, or a broken XDG configuration directory. A failed dnf upgrade can leave a package half-installed and break a critical library your desktop environment needs. A sudden power loss can corrupt the filesystem metadata. A manual chmod or chown run with a typo can lock you out of your own files. The display manager refuses to start a session it cannot trust.

Run journalctl -xe from a working terminal to see the exact abort reason. The x flag adds explanatory text and the e flag jumps to the end. Most sysadmins type journalctl -xeu gdm muscle-memory style to isolate display manager failures. Read the actual error before guessing.

The fix

You need to access the filesystem without the GUI. If Ctrl+Alt+F3 gives you a terminal, use that. If it does not, use the GRUB rescue environment. The rescue environment boots a minimal system, mounts your root filesystem, and lets you repair it safely.

Here is how to enter the rescue environment and reset your home directory permissions.

# Reboot the machine and hold Shift or press Esc during startup to show GRUB
# Highlight "Rescue a Fedora installation" and press Enter
# Accept the default options to mount your root filesystem and enter a shell
# Verify you are inside the chroot environment by checking the prompt
pwd

The rescue environment usually chroots automatically. If it does not, you must mount the filesystem manually. Fedora uses LVM by default, so your root partition is typically under /dev/mapper/.

# List block devices to find your root partition name
lsblk -f
# Mount the root filesystem to /mnt
mount /dev/mapper/fedora-root /mnt
# Bind mount virtual filesystems so chroot has access to hardware and processes
mount --bind /dev /mnt/dev
mount --bind /proc /mnt/proc
mount --bind /sys /mnt/sys
# Enter the chroot environment to operate as if you booted normally
chroot /mnt

Once inside the chroot, you can fix the ownership and permissions. The home directory itself should be readable only by the owner. The contents inherit standard permissions. SELinux contexts often drift during manual repairs, so you must restore them explicitly.

# Reset ownership of the home directory and all contents recursively
chown -R your_username:your_username /home/your_username
# Set standard permissions for the home directory itself
chmod 700 /home/your_username
# Restore SELinux security contexts that may have drifted during the repair
restorecon -Rv /home/your_username
# Exit the chroot environment and return to the rescue shell
exit
# Unmount the filesystems and reboot into the normal system
umount -R /mnt
reboot

Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. The same principle applies to home directories: user data lives in /home/, system templates live in /etc/skel/. If you accidentally overwrote a critical config, copy the default back from /etc/skel/ or reinstall the package.

Reboot before you debug. Half the time the symptom is gone.

Verify it worked

Log in normally. If the desktop loads, the repair succeeded. Open a terminal and confirm the permissions match the expected baseline.

# Check the ownership and permissions of your home directory
ls -ld ~
# Verify that SELinux contexts are correctly applied
ls -ldZ ~

The output should show drwx------ for permissions and your_username:your_username for ownership. The SELinux context should end with home_t for the directory and user_home_t for files. If the context shows unconfined_u:object_r:default_t:s0, SELinux is blocking access. Run restorecon -Rv /home/your_username again and reboot.

Check the display manager logs to confirm the session started cleanly. GDM writes session errors to the journal and to user-specific log files.

# Show recent GDM logs with explanatory text and jump to the end
journalctl -xeu gdm
# Check the user session log for desktop environment errors
cat ~/.local/share/xorg/Xorg.0.log | grep -i error

If you see Failed to start GNOME Session or Permission denied in the journal, the repair did not complete. Look for the exact file path mentioned in the error. Fix that specific file. Do not blindly change permissions on the entire home directory again.

Run journalctl -xe first. Read the actual error before guessing.

Common pitfalls and what the error looks like

The most common mistake is using the wrong username in the chown command. If you type chown -R root:root /home/your_username, the desktop environment cannot write to your directory. The login loop returns immediately. The journal will show Failed to set XDG_RUNTIME_DIR: Permission denied. Fix it by running the correct chown command with your actual username.

SELinux denials are the second most common cause. If you copied files from a live USB or restored from a backup without preserving contexts, SELinux blocks the desktop environment from reading them. The journal prints SELinux is preventing /usr/libexec/gnome-session from read access on /home/your_username/.config/gnome-session/sessions. Do not disable SELinux. Run restorecon -Rv /home/your_username to fix the contexts. SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux.

Corrupted XDG configuration directories cause silent failures. The .config and .local directories store desktop environment settings. If a power loss corrupts a JSON or XML file inside them, the session manager aborts. The error looks like Failed to parse configuration file or Invalid UTF-8 sequence. Rename the directory to force regeneration.

# Move the corrupted config directory out of the way
mv ~/.config ~/.config.bak
# Move the corrupted local data directory out of the way
mv ~/.local ~/.local.bak

The desktop environment recreates these directories on the next login with default settings. You will lose custom themes and keybindings, but you will regain access. Back up the old directories before renaming them.

Trust the package manager. Manual file edits drift, snapshots stay.

When to use this vs alternatives

Use rescue mode when the display manager blocks all console access and you cannot drop to a virtual terminal. Use a live USB when the GRUB menu is missing or the root filesystem refuses to mount due to severe corruption. Use Ctrl+Alt+F3 when you can still drop to a virtual terminal and just need to fix permissions quickly without rebooting. Use dnf reinstall gnome-session when the loop is caused by a missing desktop environment package rather than home directory corruption. Use systemctl --user reset-failed when a specific user service is stuck in a failed state and blocking session startup.

Snapshot the system before the upgrade. Future-you will thank you.

Where to go next