You see the notification, and the terminal is waiting
You see the notification that Fedora 42 is available. You want the new kernel, the updated desktop environment, and the latest security patches. You also want your dotfiles, your SSH keys, and your custom configuration to survive. You open the terminal because you know the GUI can hide errors, and you want full control over the process. You hesitate because a botched upgrade can leave you unable to boot. You need to know exactly what the commands do, how to verify the result, and how to recover if the screen goes black.
What's actually happening
dnf system-upgrade is not the same as dnf upgrade. The standard upgrade command updates packages within the current release. The system-upgrade plugin crosses the release boundary. It works in two distinct phases to keep your system safe.
The first phase is the download. The plugin resolves dependencies for the new release and downloads every package to the local cache. Your system continues to run normally. You can browse the web, compile code, or cancel the operation. If the download fails or you abort, your system is untouched. No files are modified.
The second phase is the transaction. The system reboots into a special offline environment. This environment applies the downloaded packages as a single atomic transaction. The running system is not involved. If the transaction fails, the system can often roll back to the previous state. This design prevents partial upgrades where some packages are new and others are old, which causes dependency hell and broken services.
dnf upgrade --refresh is your weekly maintenance command. It fetches fresh metadata and updates packages within the current release. dnf system-upgrade is for crossing major Fedora releases. They are different commands. Using the wrong one leaves you stuck or triggers errors.
Backup your home directory before you start. The package manager protects system files, not your data. A configuration error can still corrupt user files.
The upgrade procedure
Start by ensuring your current system is fully updated. An upgrade from an outdated base increases the risk of conflicts. Run the standard upgrade and reboot to apply any kernel changes.
sudo dnf upgrade --refresh
# --refresh forces dnf to check for new metadata from the repositories
# This ensures you are upgrading from the absolute latest state of the current release
# A clean base reduces the chance of dependency conflicts during the release jump
sudo reboot
# Reboot applies any kernel updates that dnf just installed
# Running system-upgrade with an outdated kernel can cause boot failures
Install the upgrade plugin if it is missing. Most Fedora Workstation and Server installs include it by default, but minimal containers or custom builds might not.
sudo dnf install dnf-plugin-system-upgrade
# The plugin provides the system-upgrade subcommand
# This command is safe to run even if the plugin is already installed
# dnf will report that the package is already the latest version
Download the packages for the target release. Replace 42 with the actual version number you want to upgrade to. Check the Fedora release schedule to confirm the version exists.
sudo dnf system-upgrade download --releasever=42
# --releasever tells dnf which Fedora version to target
# Replace 42 with the actual version number you want to upgrade to
# This command resolves dependencies and downloads all packages to the cache
# The system remains stable during this phase. You can abort without damage.
If you see Error: Transaction test error: package ... conflicts with ..., stop. Do not force the transaction. The conflict usually comes from a third-party repository or a package that was manually installed. Check your repo files and remove the conflicting package before retrying.
Once the download completes, trigger the reboot. The system will restart immediately. Do not interrupt the process. The screen may show a progress bar or a static message for several minutes. The offline transaction is running.
sudo dnf system-upgrade reboot
# This command triggers the offline transaction
# The system reboots immediately into a special upgrade environment
# Do not interrupt the process once the reboot starts
# The screen may show a progress bar or a static message for several minutes
Reboot after the kernel update. An old kernel causes upgrade conflicts.
Post-upgrade verification and cleanup
After the system boots into the new release, log in and verify the version. Check the release file and the kernel version.
cat /etc/fedora-release
# Displays the human-readable release string
# This file is updated by the upgrade transaction
# It confirms the system recognizes the new release
rpm -E %fedora
# Expands the rpm macro to the numeric release version
# This is useful for scripts that need the version number
Run dnf distro-sync to finalize the package state. The transaction installs the new packages, but distro-sync handles obsoletes, downgrades, and version mismatches that the transaction might miss. It aligns your installed packages with the new repository state.
sudo dnf distro-sync
# distro-sync aligns your installed packages with the new repository state
# It handles obsoletes, downgrades, and version mismatches automatically
# This is the safest way to finalize the upgrade and remove retired packages
sudo dnf autoremove
# Removes dependencies that were pulled in by old packages but are no longer needed
# This cleans up leftover libraries and kernel modules from the previous release
sudo dnf list extras
# Lists packages installed from third-party repositories
# Review this list to ensure your custom software is still supported
Configuration files in /etc/ are preserved during the upgrade. Files in /usr/lib/ ship with packages and are overwritten. If you edited a file in /usr/lib/, your changes are gone. Edit /etc/ only. Never edit /usr/lib/.
Run journalctl -xe to check for failed services. The x flag adds explanatory text and the e flag jumps to the end. Look for [FAILED] markers. Most services restart automatically, but some might need manual intervention.
journalctl -xe
# -x adds explanatory text from man pages and documentation
# -e jumps to the end of the journal to show recent events
# Look for [FAILED] markers and service names that did not start
# This helps you catch issues before they affect your workflow
Run dnf distro-sync after the reboot. It fixes the edge cases the transaction missed.
Common pitfalls and error recovery
Third-party repositories are the most common cause of upgrade failures. RPM Fusion usually tracks Fedora releases, but custom repos might not have a configuration file for the new version. If a repo is missing, dnf will complain about missing metadata. Disable the repo temporarily if needed.
If you see Error: Failed to download metadata for repo 'custom-repo', the repository does not support the new release. Check the repo URL or disable the repo file in /etc/yum.repos.d/. You can re-enable it later once the repo maintainer updates their files.
SELinux might need to relabel files after a major upgrade. You might see a message about .autorelabel during boot. This process scans the filesystem and restores security contexts. It takes time. Wait for it. Do not force reboot. Interrupting the relabel can leave files with incorrect contexts and cause access denials.
If the system fails to boot after the upgrade, check the GRUB menu. Select the older kernel entry if it exists. Boot into the old system. Run dnf distro-sync to revert the package state, or investigate the error. The old kernel is your safety net.
Error: Transaction test error:
package python3-3.12.x conflicts with python3-3.13.y
The dnf system-upgrade command will refuse to proceed and print a conflict error like the one above. The conflict is intentional. Read the error message. Identify the conflicting package. Remove or update the package before retrying the download. Forcing the transaction can break the system.
If the boot menu is gone, GRUB rescue is your friend, not your enemy. Use the rescue shell to locate the boot partition and reinstall GRUB.
When to use this vs alternatives
Use dnf system-upgrade when you want to preserve your configuration and user data while moving to the next release. Use a clean install when your system has accumulated years of cruft or you suspect deep configuration drift. Use dnf upgrade --refresh when you only need the latest security patches and bug fixes within your current release. Use rpm-ostree upgrade when you are running Fedora Silverblue or Kinoite and need the immutable update path. Use liveusb-creator or dd to create a bootable installer when you want to test the new release on a different machine before upgrading your main system.
Trust the package manager. Manual file edits drift, snapshots stay.