How to Upgrade Fedora 39 to Fedora 40

Upgrade Fedora 39 to Fedora 40 using the dnf system-upgrade command to download and reboot into the new release.

The upgrade scenario

You run dnf upgrade on a Friday afternoon and watch a wall of package updates scroll past. The system reboots, but the login screen still says Fedora 39. You expected a major release jump, but the standard package manager only handles minor updates within the same release cycle. Crossing from 39 to 40 requires a different workflow. The default dnf transaction will refuse to swap out core libraries, the kernel, and system daemons in a single pass because the dependency graph changes too drastically. You need the dedicated system upgrade plugin.

What the upgrade process actually does

Fedora treats major version jumps as a complete environment swap, not a simple package refresh. Think of it like replacing the foundation of a house while the family is still inside. The dnf system-upgrade plugin stages every package for the target release, resolves the new dependency tree, and writes the files to disk. It does not apply them immediately. The staged packages sit in the RPM database waiting for a reboot. When the system restarts, the initramfs and bootloader load the new kernel, and the package manager applies the staged transaction before the display manager starts. This two-phase approach prevents a broken state if the power cuts out or a download fails halfway through.

The process also handles configuration drift and security contexts automatically. RPM compares every file in /etc/ against the new package defaults. If you modified a configuration file, RPM preserves your version and drops the new default as a .rpmnew file. SELinux relabels the filesystem in the background during the first boot. The bootloader regenerates its configuration to match the new kernel series. You do not need to run manual migration scripts. The package manager handles the heavy lifting.

Convention aside: dnf upgrade --refresh is your weekly maintenance command. It pulls the latest patches for your current release. dnf system-upgrade is strictly for crossing major Fedora releases. They use different transaction locks and different repository metadata. Running the wrong one will either do nothing or leave your package database in a conflicted state.

Running the upgrade

The process splits into two explicit steps. First, you download and stage the new packages. Second, you trigger the reboot that applies them. You must run both commands with root privileges. Keep a stable internet connection active throughout the download phase. A dropped connection will corrupt the cache and force you to clear the database and start over.

Here is how to stage the Fedora 40 packages without touching the running system.

sudo dnf system-upgrade download --releasever=40
# --releasever tells dnf which target repository to pull metadata from
# The plugin resolves dependencies and downloads every RPM to /var/cache/dnf
# No files are installed yet. The running system remains on Fedora 39

Wait for the command to finish. You will see a summary of packages to upgrade, downgrade, and remove. If the transaction test passes, the cache fills up. Do not interrupt the download. A partial cache will force you to clear the database and start over.

Once the download completes, you trigger the actual upgrade.

sudo dnf system-upgrade reboot
# This command marks the staged transaction for execution on next boot
# It drops you out of the current shell immediately
# Save your work and close all applications before running this

The system will shut down and restart automatically. The first boot after a major upgrade takes longer than usual. You will see package progress bars scrolling across a black terminal screen. This is the RPM database applying the staged changes. Do not force power off during this phase. The initramfs rebuild and bootloader update happen here. Interrupting it will drop you into emergency mode.

Trust the package manager. Manual file edits drift, snapshots stay. Let the staged transaction run to completion.

Verifying the new release

After the system finishes applying packages, it drops you at the login prompt or the graphical display manager. Log in and open a terminal. The first thing you should check is the kernel version and the release ID.

Here is how to confirm the system is actually running Fedora 40.

cat /etc/fedora-release
# Prints the exact release string, e.g., "Fedora release 40 (Forty)"
uname -r
# Shows the kernel version, which should match the 40 series baseline
dnf repolist
# Lists active repositories. All URLs should point to releases/40/

If the output matches, the upgrade succeeded. You can now run a standard refresh to pull any post-upgrade patches that were released after the base image was built.

sudo dnf upgrade --refresh
# --refresh forces dnf to ignore cached metadata and pull fresh repo data
# This catches security fixes and bug patches released during your upgrade window

Run dnf upgrade --refresh immediately after a major jump. The base image is never the final state.

Common pitfalls and error messages

Major upgrades fail for predictable reasons. Most errors come from third-party repositories, leftover configuration files, or insufficient disk space.

The most common blocker is a third-party repository that has not yet published Fedora 40 packages. If you have RPM Fusion, Flatpak remotes, or custom vendor repos enabled, dnf will try to pull from them and fail. The transaction test will abort with a dependency error.

Error: Transaction test error:
package kernel-6.7.0-100.fc40.x86_64 requires kernel-modules = 6.7.0-100.fc40, but none of the providers can be installed

Disable non-Fedora repositories before starting the download phase. You can re-enable them after the reboot.

sudo dnf config-manager --set-disabled '*'
sudo dnf config-manager --set-enabled fedora updates
# This isolates the transaction to official Fedora repositories only
# Third-party repos can be re-enabled safely after the new release is active

Disk space is the second silent killer. The staging process downloads every RPM to /var/cache/dnf before applying it. A minimal desktop installation needs at least 15 gigabytes of free space in the root partition. If the partition is full, the download command will hang or fail with an I/O error. Check your available space before you begin.

df -h /
# Look at the "Avail" column. Anything under 15G is risky for a major upgrade
sudo dnf clean all
# Clears old package caches and frees space before the staging phase begins

Configuration file conflicts appear during the reboot phase. When a package updates a file in /etc/, RPM compares the new version against your modified version. If they differ, RPM saves the new file with a .rpmnew extension and keeps your old version. The system will boot, but some services might behave unexpectedly. Check for these files after the upgrade.

sudo find /etc -name "*.rpmnew" -type f
# Lists configuration files where the package maintainer shipped a new default
# Review each file and merge your custom settings into the new version
# Do not blindly overwrite your config. You will lose custom firewall rules or daemon settings

Run journalctl -xe if a service fails to start after boot. Read the actual error before guessing.

Post-upgrade maintenance

A successful package swap is only the first step. You need to verify that your hardware drivers, desktop environment, and background services survived the transition.

Kernel module updates often break proprietary GPU drivers or custom network adapters. Fedora ships open-source drivers by default, but third-party modules require rebuilding against the new kernel headers. Check your graphics stack immediately.

glxinfo | grep "OpenGL renderer"
# Confirms the GPU driver is active and rendering correctly
lsmod | grep -E "nvidia|amdgpu|nouveau"
# Shows which kernel modules are currently loaded for your hardware

Desktop environment extensions and GNOME/KDE plugins frequently break across major releases. The new release ships updated GTK or Qt libraries. Old extensions will fail to load and leave you with a bare window manager. Disable third-party extensions before logging into the graphical session. Re-enable them one by one after confirming the base desktop works.

SELinux denials show up in journalctl -t setroubleshoot with a one-line summary. Read those before disabling SELinux. Most post-upgrade denials come from custom scripts or non-standard service paths. Fix the file context with restorecon or write a proper policy module. Do not switch to permissive mode as a permanent fix.

Convention aside: Config files in /etc/ are user-modified. Files in /usr/lib/ ship with the package. Edit /etc/. Never edit /usr/lib/. Package updates will overwrite changes in /usr/lib/ and break your system.

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

Choosing your upgrade path

Fedora offers multiple ways to move between releases. The right tool depends on your hardware, your tolerance for downtime, and your backup strategy.

Use dnf system-upgrade when you want a seamless in-place transition on a standard Workstation or Server installation. Use a clean installation when your system has accumulated years of package drift, broken third-party dependencies, or custom kernel patches. Use rpm-ostree when you are running Fedora Silverblue or Kinoite and need atomic, rollback-capable updates. Stay on the current release when your hardware drivers or proprietary software only supports the older kernel series.

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

Where to go next