You upgraded and now something is broken
You ran sudo dnf upgrade to keep your system current. The update finished, you rebooted, and now your Wi-Fi is dead or the desktop environment refuses to start. The new package version has a regression. You need to go back to the version that worked. Fedora's package manager handles this, but you have to choose the right tool for the job. Forcing a downgrade without checking dependencies can break the whole system.
Run dnf downgrade before you panic. The repo likely still has the previous build.
What is actually happening
Package managers treat upgrades as a one-way street by default. When you install a newer version, dnf removes the older files and records the transaction. Downgrading reverses that flow. You are asking dnf to replace current files with older ones and resolve any dependencies that the newer version pulled in.
The catch is availability. Fedora repositories rotate. Older packages disappear after a few releases. If the repo does not have the old version, dnf cannot find it. You also need to watch for dependencies. Package B might now require the new version of Package A. Downgrading A without downgrading B creates a conflict.
Fedora repositories follow a strict retention policy. When a new Fedora release ships, the repositories for older releases are archived. Packages from two releases ago may no longer be available in the standard mirrors. If you are on Fedora 40 and try to downgrade to a package from Fedora 38, the repo will not have it. You must enable the archive repo or fetch the RPM manually. This rotation keeps mirror bandwidth manageable. It also means you cannot downgrade indefinitely. Plan your downgrades close to the time of the upgrade.
The dnf transaction history is a local database that records every change. It tracks which packages were installed, updated, or removed in each run. This history is the safety net for batch operations. When you run sudo dnf upgrade, dnf creates a transaction. If that transaction updates fifty packages and one of them breaks your system, downgrading that one package might not be enough. Other packages in the transaction might depend on the new version. Undoing the transaction restores the entire set of packages to their previous state. This is safer than picking individual packages to downgrade.
Check dnf history before you guess. The transaction ID tells you exactly what changed.
How to downgrade
Choose the method based on how the breakage happened. If a single package caused the issue, downgrade that package. If a batch update broke multiple components, undo the transaction.
Downgrade a single package
Start with the simplest path. dnf downgrade finds the highest available version lower than what you have. This command is safer than manually installing an older version because dnf resolves dependencies automatically. It will downgrade related packages if they are required by the older version.
Here is how to downgrade a package to the next available older version.
sudo dnf downgrade <package-name>
# WHY: Tells dnf to look for the next lower version in enabled repos.
# WHY: dnf resolves dependencies automatically, downgrading related packages if needed.
If the repository has the older version, dnf will propose the transaction. Review the summary. It will list the package being downgraded and any dependencies that must also be downgraded. Confirm the transaction.
Undo a transaction
If the breakage came from a large batch update, undoing the transaction is cleaner than downgrading packages one by one. This method reverses the entire update atomically. It restores all packages to their state before the transaction ran.
Here is how to find and undo a specific transaction.
dnf history list
# WHY: Shows transaction IDs. Look for the ID that installed the bad update.
sudo dnf history undo <ID>
# WHY: Reverses the entire transaction atomically.
# WHY: Restores all packages to their state before that transaction ran.
The dnf history list command shows a table of recent transactions. Find the ID that corresponds to the upgrade that caused the problem. Run sudo dnf history undo <ID> to reverse it. dnf will calculate the reverse transaction and ask for confirmation.
Trust the transaction. dnf history undo is atomic. Partial undos leave the system in a broken state.
Downgrade to a specific version
Sometimes you need a specific version, not just the previous one. You might need to skip a version that is known to be broken, or you might need a version that is not the immediate predecessor.
Here is how to list available versions and install a specific one.
dnf list --showduplicates <package-name>
# WHY: Lists all versions available in repos, including installed and older ones.
sudo dnf install <package-name>-<version>-<release>.fc40
# WHY: Pinpoints the exact NEVRA string.
# WHY: Using install with an older version triggers a downgrade transaction.
The --showduplicates flag is essential. Without it, dnf list only shows the latest version. With it, you see every version available in the enabled repositories. Copy the full package name including the version and release string. Pass that string to dnf install. dnf detects that the version is older than the installed version and performs a downgrade.
Install from a local RPM
If the repository has rotated and dropped the version you need, you might have a local RPM file or you might need to fetch one from Koji. Koji is the Fedora build system and archives all builds. You can download older RPMs from koji.fedoraproject.org.
Here is how to install a local RPM and let dnf handle the downgrade.
sudo dnf install /path/to/older-package.rpm
# WHY: dnf handles local RPMs by checking dependencies and downgrading if needed.
# WHY: This is safer than rpm -i because dnf resolves the dependency graph.
Never use rpm -i for downgrades. rpm does not check dependencies or resolve conflicts. dnf will use the local file, check the dependency graph, and downgrade the package safely. If dependencies are missing, dnf will try to resolve them from the repositories.
Lock a package version
If you anticipate instability or you are waiting for a fix, you can lock a package to prevent it from upgrading during routine maintenance. This is a proactive measure.
Here is how to lock a package version.
sudo dnf install 'dnf-command(versionlock)'
# WHY: Installs the plugin that provides version locking functionality.
sudo dnf versionlock add <package-name>
# WHY: Prevents dnf from upgrading this package during future transactions.
sudo dnf versionlock list
# WHY: Shows all locked packages so you can manage them later.
The versionlock plugin is not installed by default. Install it once, then use it to lock packages. Locked packages are skipped during dnf upgrade. You can still downgrade or update a locked package explicitly. Remove the lock with sudo dnf versionlock delete <package-name> when you are ready to upgrade again.
Lock the version if the upstream is unstable. dnf versionlock saves you from the next dnf upgrade.
Verify the downgrade
Always check the installed version after the transaction completes. Do not assume the downgrade succeeded just because the command exited without error.
Here is how to verify the installed version.
rpm -q <package-name>
# WHY: Queries the RPM database for the installed version.
# WHY: Confirms the downgrade persisted and the correct version is active.
The output shows the package name, version, release, and architecture. Compare this with the version you expected. If the version is still the new one, the downgrade failed or was skipped. Check the dnf output for warnings.
Check the version number. Don't assume the transaction succeeded just because the command exited.
Common pitfalls and errors
Downgrades can fail for several reasons. Understanding the error messages helps you fix the problem quickly.
If you see Error: Nothing to do, the repository has rotated and removed the older version. You cannot downgrade to a version that does not exist in your enabled repos. Check Koji for archived builds or enable the archive repository for your Fedora version.
If you see Transaction test error: package ... conflicts with ..., you are trying to downgrade a package that has strict version constraints. Other packages depend on the newer version. dnf will list the conflicting packages. You may need to downgrade those packages as well. Use dnf downgrade to let dnf resolve the dependency chain. If dnf cannot resolve the conflict, you may need to use dnf history undo to revert the entire transaction.
Kernel packages require special attention. Fedora installs multiple kernels by default. A downgrade of the kernel package does not remove the new kernel. It installs the older kernel alongside the new one. You must reboot and select the older kernel from the GRUB menu. If the older kernel works, you can remove the new kernel later. If you remove the new kernel before testing the old one, you risk having no bootable kernel if the old one fails. Always test the downgraded kernel before removing the current one.
Config files in /etc/ are preserved during downgrades. dnf keeps your local changes. If a config file format changed between versions, the old package might fail to read the new config. Check logs in journalctl -xe after rebooting. If a service fails to start, look for configuration errors. You may need to restore the default config file from the package or adjust your settings to match the older version.
If SELinux blocks the downgraded service, run sudo restorecon -Rv /path/to/directory to reset contexts. SELinux contexts are usually preserved, but downgrading can sometimes leave files with incorrect labels.
Reboot after downgrading the kernel. The old kernel won't run until you select it in GRUB.
When to use each method
Use dnf downgrade when you want to revert a single package to the highest available older version. Use dnf history undo when a batch update broke multiple components and you need to restore the system state atomically. Use dnf install <old-version> when you need a specific version number that is not the immediate predecessor. Use a local RPM file when the repository has rotated and dropped the version you need. Use dnf versionlock when you want to prevent a package from upgrading during routine maintenance.