Recover from a Failed Update on Fedora

When a DNF update fails or leaves your system in a broken state, you can complete the interrupted transaction, roll back packages, or use the live environment to repair the installation.

You run sudo dnf upgrade on a Tuesday afternoon

The download stalls, the power flickers, or you accidentally close the terminal window. Wednesday morning, the system either refuses to boot, drops to a broken desktop, or throws dependency errors on every command. The update process stopped mid-stream and left the package manager in an inconsistent state. You need to restore a working system without wiping your configuration files.

What is actually happening

Fedora uses DNF as its package manager, which relies on RPM to handle the actual file installation and database tracking. When an update runs, DNF stages a transaction. It downloads packages, checks dependencies, and then hands them to RPM to unpack. RPM writes every change to a local database in /var/lib/rpm. If the process dies before RPM finishes writing, the database and the filesystem disagree. Packages might be half-installed, configuration files might be missing, or the kernel might be swapped out before the initramfs is rebuilt. The system is not broken beyond repair. The package manager just needs a clear path to reconcile the two states.

Resume or clean up an interrupted transaction

Start by checking whether DNF can automatically recover the interrupted transaction. DNF keeps a lock file and a transaction journal. If the lock is stale, DNF will prompt you to clean it up. Run the synchronization command to align your installed packages with the repository state.

sudo dnf distro-sync
# WHY: distro-sync updates installed packages to match the repo version,
# even if it means downgrading a manually upgraded package.
# It also resolves dependency loops left by a crashed transaction.

If the command hangs or complains about corrupted metadata, clear the local cache and force a fresh repository check. The cache often holds stale headers from the failed run.

sudo dnf clean all
# WHY: removes cached metadata, headers, and RPM database locks.
# This forces DNF to re-download repository indexes on the next run.
sudo dnf upgrade --refresh
# WHY: --refresh ignores cached metadata and fetches fresh repo data.
# This is the standard weekly maintenance command on Fedora.

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

Roll back a specific transaction with dnf history

Sometimes the update finishes successfully but breaks a service or removes a critical dependency. DNF records every transaction in a numbered history log. You can inspect the log and reverse a specific transaction without reinstalling the entire system.

dnf history
# WHY: lists all past DNF transactions with ID, command, and date.
# Look for the ID that matches the failed or problematic update.

Pick the transaction ID and inspect exactly what changed. This shows added, removed, and downgraded packages.

sudo dnf history info 42
# WHY: replaces 42 with your actual transaction ID.
# Shows the exact package list and dependency changes.

Once you confirm the transaction caused the issue, reverse it. DNF will reinstall the previous versions and restore the removed packages.

sudo dnf history undo 42
# WHY: undoes the transaction by reinstalling old packages and
# removing the ones added in that specific run.
# Always review the info output before running undo.

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

Boot into the previous kernel

A kernel update is the most common cause of boot failures. The new kernel might lack a driver for your storage controller, or the initramfs might fail to build. The GRUB bootloader keeps the previous kernel available by default. You can select it manually and remove the broken version from a working session.

Hold Shift on BIOS systems or tap Esc repeatedly on UEFI systems during startup. The GRUB menu appears. Use the arrow keys to select the older kernel entry and press Enter. Once the system boots, verify which kernel is currently running.

uname -r
# WHY: prints the exact version string of the running kernel.
# Compare this to the list of installed kernels.
sudo dnf list installed kernel
# WHY: shows all kernel packages currently on the system.
# Identify the broken version that does not match uname -r.

Remove the problematic kernel package. DNF will clean up the associated modules and initramfs images.

sudo dnf remove kernel-6.8.5-200.fc40.x86_64
# WHY: replaces the version string with the exact broken kernel package.
# This prevents GRUB from offering it on the next boot.

If the boot menu is gone, GRUB rescue is your friend, not your enemy.

Repair from a Live environment

When the system refuses to boot entirely, you need an external environment to repair the root filesystem. Boot from a Fedora Live USB, open a terminal, and mount your system partition. Identify the correct partition first.

lsblk
# WHY: displays block devices and mount points.
# Find the partition containing your root filesystem, usually /dev/nvme0n1p2 or /dev/sda2.

Mount the root partition and bind the virtual filesystems. The chroot environment needs access to devices, process information, and system mounts to run DNF correctly.

sudo mount /dev/nvme0n1p2 /mnt
# WHY: mounts your actual root partition to the temporary /mnt directory.
sudo mount --bind /dev /mnt/dev
sudo mount --bind /proc /mnt/proc
sudo mount --bind /sys /mnt/sys
# WHY: binds the Live environment's virtual filesystems into the chroot.
# DNF and RPM require /dev, /proc, and /sys to function.
sudo chroot /mnt
# WHY: switches the root directory to your mounted system.
# You are now operating inside the broken installation.

Run the synchronization command again from inside the chroot. This repairs the package database and reinstalls missing files.

dnf distro-sync
# WHY: runs inside the chroot to fix the broken transaction.
# Use sudo only if the chroot dropped you into a non-root shell.

Exit the chroot, unmount the filesystems, and reboot. The system should recover cleanly.

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

Handle immutable variants like Silverblue

Immutable Fedora variants handle updates differently. They use rpm-ostree to compose atomic OS trees. A failed update never touches your running system. The new deployment sits in the background until you reboot. If the reboot fails, the system automatically rolls back to the previous tree. You can also trigger a manual rollback from the command line.

rpm-ostree status
# WHY: shows the current deployment and any pending updates.
# Look for the "deployments" section to see available versions.
sudo rpm-ostree rollback
# WHY: sets the previous deployment as the default boot target.
# Your home directory and configuration files remain untouched.

Reboot to apply the rollback. The immutable model guarantees a known-good base image.

Verify it worked

Confirm the system is stable by checking the package manager state and reviewing recent logs. Run a clean upgrade cycle to ensure the repository metadata is synchronized.

sudo dnf check
# WHY: scans the RPM database for broken dependencies or conflicts.
# A clean output means the transaction is fully resolved.
journalctl -xeu dnf
# WHY: shows recent DNF logs with explanatory context.
# The x flag adds helpful annotations, e flag jumps to the end.

Check for SELinux denials if a service still refuses to start. SELinux logs appear in a dedicated stream.

journalctl -t setroubleshoot
# WHY: filters logs for SELinux policy violations.
# Read the one-line summary before disabling the security context.

Run journalctl first. Read the actual error before guessing.

Common pitfalls and what the error looks like

Forcing package operations with --skip-broken or --best often masks the real problem. DNF will leave the system in a partially updated state, which causes cascading failures on the next run. If you see the following conflict, stop immediately.

Error: Transaction test error: package python3-3.12.7-1.fc40.x86_64 conflicts with python3-3.13.1-1.fc40.x86_64

The conflict is intentional. Read the dependency chain before overriding. DNF prevents you from installing two major versions of the same interpreter simultaneously.

Editing files in /usr/lib/ breaks package updates. Those files belong to the package maintainer. DNF will overwrite them on the next upgrade. Always place custom configuration in /etc/. The system is designed to preserve /etc/ across updates.

Ignoring the initramfs rebuild is a common mistake. When you remove a kernel or install a driver, the initramfs must regenerate. Run sudo dracut --force if you suspect the boot image is stale. The system will fail to mount the root filesystem without a valid initramfs.

When to use this vs alternatives

Use dnf distro-sync when the package database is out of sync with the repository state. Use dnf history undo when a specific transaction removed a critical dependency or broke a service. Use the GRUB menu when the new kernel fails to load but the previous version still works. Use a Live USB chroot when the system drops to an emergency shell or refuses to boot entirely. Use rpm-ostree rollback when you are running Silverblue or Kinoite and need to revert to a previous atomic deployment. Stay on the upstream Workstation if you only deviate from the defaults occasionally.

Where to go next