You click the update button and the terminal freezes
You see the orange shield icon in the system tray, or you type sudo dnf upgrade and the terminal hangs for three minutes. You wonder if the system is stuck. It isn't. DNF is calculating a dependency graph across thousands of packages. When the output finally scrolls, you see a list of packages to upgrade, a total download size, and a prompt. You press y. The download starts. Then the install. Then the system asks for a reboot.
This routine keeps your Fedora installation secure and functional. It also introduces risks if you skip the details. A botched update can leave you with a broken desktop or a kernel that won't boot. Running updates correctly means understanding what DNF is doing, verifying the result, and knowing how to recover if something goes wrong.
Reboot before you debug. Half the time the symptom is gone.
What's actually happening
DNF is a dependency resolver and transaction manager. It treats your system state as a database. When you request an update, DNF fetches metadata from the repositories. Metadata describes every available package, its version, its dependencies, and what files it provides. DNF compares this metadata against your installed packages. It builds a graph of relationships. It then solves for a new state where all dependencies are satisfied and the requested packages are at their latest versions.
The result is a transaction. A transaction is atomic. DNF downloads the RPMs, runs a test installation in memory to check for conflicts, and only then applies the changes. If the test fails, DNF aborts and leaves your system untouched. This atomic behavior is your safety net. It prevents half-installed packages and broken dependencies.
Fedora uses module streams for some packages like PHP or PostgreSQL. dnf upgrade respects the enabled stream. It will not switch streams automatically. This prevents surprise version jumps. If you need a different version, you must switch streams explicitly. dnf upgrade handles the packages within the current stream. This behavior keeps your environment stable.
Convention aside: dnf upgrade is the standard command. dnf update is an alias that exists for backward compatibility. Use upgrade in scripts and muscle memory. The behavior is identical, but upgrade is the canonical name in the current DNF codebase.
Run dnf upgrade --refresh. Stale metadata causes more confusion than broken packages.
Apply all available updates
Here's how to update the system and force a metadata refresh to avoid cache issues.
sudo dnf upgrade --refresh # --refresh forces metadata download to avoid stale cache errors
The --refresh flag is essential for reliable updates. Without it, DNF uses cached metadata. If a repository updated its packages while your cache was valid, DNF might miss new versions or report false dependency conflicts. Refreshing ensures DNF sees the current state of the repositories. This flag adds a few seconds to the command but prevents hours of debugging caused by stale data.
Check for updates without installing.
sudo dnf check-update # Lists available updates without installing anything
Run this command before you commit to an upgrade. It shows you exactly what will change. Look for kernel packages. If you see kernel, kernel-core, and kernel-modules, a reboot is required after the update. Review the list for unexpected packages. If a package you don't recognize appears, check its description before proceeding.
Update a single package.
sudo dnf upgrade firefox # Upgrades only firefox and its dependencies
Use this when you need a specific fix but don't want to update the entire system. DNF will still resolve dependencies. If firefox requires a newer library, DNF upgrades that library as well. This keeps the system consistent.
Trust the transaction. DNF rolls back automatically if the test fails. Manual edits drift, transactions stay consistent.
Verify the update
Here's how to confirm the update completed and review what changed.
sudo dnf history info last # Displays details of the most recent transaction
DNF records every transaction in a local history database. This command shows the ID, date, and package list of the last operation. Use this to verify the update completed successfully. If you need to undo changes later, you reference the transaction ID from this output.
Check the running kernel version.
uname -r # Prints the currently running kernel version
After an update, check the running version. If it does not match the new version from the update, reboot the system. The kernel cannot be replaced while the system is active. DNF installs the new kernel alongside the old one. Fedora retains multiple kernel versions. By default, the last three kernels are kept. This provides a fallback if the new kernel causes hardware issues.
If the boot menu is gone, GRUB rescue is your friend, not your enemy.
Common pitfalls and errors
DNF will refuse to proceed if it detects a problem. These errors protect your system. Read them carefully before forcing anything.
You see Error: Transaction test error: package python3-3.12.x conflicts with python3-3.13.y. This error means two packages claim the same file or provide the same virtual capability. DNF refuses to proceed because the conflict would break the system. Do not force the install. Check if you have enabled a third-party repository like RPM Fusion or a COPR repo that provides a conflicting package. Disable the conflicting repo and retry.
You see GPG check FAILED. This error indicates a signature verification failure. The package metadata or RPM does not match the trusted GPG key. This can happen if a repository key expired or if the package was tampered with. Check the repository configuration. If you recently added a repo, ensure you imported the correct key. Never use --nogpgcheck to bypass this error. It disables security verification and exposes your system to malicious packages.
You see Cannot prepare internal mirrorlist: No URLs in mirrorlist. This error means DNF cannot reach the repository servers. Check your network connection. Verify that /etc/resolv.conf contains valid DNS servers. If you are behind a proxy, configure the proxy in /etc/dnf/dnf.conf.
Convention aside: journalctl -xe reads better than journalctl alone. The x flag adds explanatory text and the e flag jumps to the end. If an update breaks the boot, check the journal for errors. journalctl -xe helps you find the failure point quickly. SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux.
Run journalctl first. Read the actual error before guessing.
Automatic updates
Fedora provides dnf-automatic for scheduled updates. This service runs a timer that checks for updates daily. You can configure it to download updates automatically or apply them as well.
Install the automatic update service.
sudo dnf install dnf-automatic # Installs the service and timer for automated updates
Configure the update policy.
# /etc/dnf/automatic.conf
apply_updates = no # Set to yes to auto-apply updates, no to only download
download_updates = yes # Download updates in the background
Edit the configuration file to set your policy. Desktop users often prefer apply_updates = no to review updates before rebooting. Servers may use yes for security patches. Enable the timer to start the schedule.
Start the timer.
sudo systemctl enable --now dnf-automatic.timer # Starts the timer and enables it at boot
Check the timer status.
systemctl status dnf-automatic.timer # Shows the next scheduled run and current state
The timer runs daily by default. You can modify the schedule in /etc/systemd/system/dnf-automatic.timer.d/override.conf if needed.
Snapshot the system before the upgrade. Future-you will thank you.
Recovery: Undoing a bad update
If an update breaks your system, DNF history allows you to undo the changes. This is a powerful recovery tool. You can revert to the state before the problematic transaction.
List recent transactions.
sudo dnf history list # Lists all transactions with their IDs
Find the transaction ID that caused the issue. Run the undo command with that ID.
sudo dnf history undo <id> # Reverts the changes from a specific transaction ID
DNF will reverse the package changes. This restores the previous versions of the affected packages. If the system is unbootable, you can use the rescue environment or boot from a live USB to run the undo command. Mount the root filesystem and chroot into it first.
Convention aside: Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. If a package update overwrites a file in /etc/, DNF usually keeps your version and creates a .rpmnew file. Check for .rpmnew files after major updates and merge changes manually.
When to use this vs alternatives
Use sudo dnf upgrade --refresh when you want to update all packages and ensure fresh repository metadata.
Use sudo dnf check-update when you want to preview available updates before committing to a transaction.
Use sudo dnf upgrade <package> when you only need to update a specific package and its dependencies.
Use dnf-automatic when you want the system to handle updates on a schedule without manual intervention.
Use sudo dnf system-upgrade when you are moving between major Fedora releases, such as from Fedora 40 to Fedora 41.
Use sudo dnf history undo <id> when an update broke your system and you need to revert to the previous state.
Use sudo dnf clean all when DNF reports disk space errors or you need to clear cached metadata and RPM files.
Trust the package manager. Manual file edits drift, snapshots stay.