How to roll back a package update¶
Use this guide when an update has installed a new version of a package that doesn't work for you, and you need the previous version back while you investigate or wait for a fix.
How reliable a rollback is depends on the distribution. Installing an older package is easy everywhere, if you can still get it: point-release distributions usually keep earlier versions in their repositories, while rolling distributions rely on your local package cache or an archive. No package manager reverses what the newer version's installation scripts did, such as migrating a database or a configuration format, so a rollback can leave the older version facing data it doesn't understand.
Back up the package's data first
If the package keeps state (a database server, a mail server, anything with files under /var/lib), stop its service and back up that state before you downgrade.
Check the upstream release notes for whether the new version changed its data format; if it did, restore the backup taken before the update rather than pointing the old version at migrated data.
Before you begin¶
- You need a shell with
sudoon the machine. - Replace
<PACKAGE>with the name of the package and<VERSION>with the version to go back to, as found in step 1. The examples usejqon Debian and Ubuntu,wgeton the RHEL family,treeon Arch andapp-text/treeon Gentoo. - Downgrading is less tested than upgrading by every distribution. Try it on a test machine first where you can.
Steps¶
-
Find which version was installed before, and which versions are available.
/var/log/apt/history.logrecords every change, with the old and new version in brackets:$ grep '<PACKAGE>:' /var/log/apt/history.log Install: libonig5:amd64 (6.9.9-1+b1, automatic), jq:amd64 (1.7.1-6+deb13u3), libjq1:amd64 (1.7.1-6+deb13u3) Upgrade: jq:amd64 (1.7.1-6+deb13u3, 1.7.1-6+deb13u4), libjq1:amd64 (1.7.1-6+deb13u3, 1.7.1-6+deb13u4) $ apt-cache policy <PACKAGE> jq: Installed: 1.7.1-6+deb13u4 Candidate: 1.7.1-6+deb13u4 Version table: *** 1.7.1-6+deb13u4 500 500 http://deb.debian.org/debian-security trixie-security/main amd64 Packages 100 /var/lib/dpkg/status 1.7.1-6+deb13u3 500 500 http://deb.debian.org/debian trixie/main amd64 PackagesOlder logs are rotated to
history.log.1.gzand so on; read them withzgrep. -
Check whether the older version can still be installed. It can if
apt-cache policylists it, or if its.debfile is still in/var/cache/apt/archives/:Ubuntu's release pocket (
resolute) keeps the version the release shipped with, while Debian's main suite (trixie) is replaced at each point release, as in the example above. Each update suite keeps only its newest version: an intermediate security update is gone once a newer one replaces it.aptdoesn't keep the packages it downloads by default, whileapt-getkeeps them untilapt-get clean. For Debian, every version ever published is also available from snapshot.debian.org. -
Install the older version, together with any packages that require exactly the same version.
jqdepends on exactly its own version oflibjq1, so both go back together:Without
-y,apt-getlists the packages it will downgrade and asks for confirmation; check the list. If it wants to remove other packages, stop and find out why.
On Ubuntu 26.04, apt 3.2 also numbers its transactions: apt history-list lists them, and apt history-info <ID> shows the old and new version of each package a transaction changed, which is a quicker way to do step 1.
It also has an apt history-undo command, but with apt 3.2.0, undoing an upgrade left the new versions installed, so downgrade with apt-get install as shown.
Debian 13's apt 3.0 has none of these commands.
dnf records every transaction with the exact package versions it changed, and the RHEL family's repositories usually keep earlier builds of a package within the current minor release, so you can usually reverse an update directly.
-
Find the transaction that upgraded the package:
$ dnf history list <PACKAGE> ID | Command line | Date and time | Action(s) | Altered ------------------------------------------------------------------------------- 2 | -y upgrade wget | 2026-11-07 13:29 | Upgrade | 1 1 | -q install -y wget-1.24. | 2026-11-07 13:29 | Install | 1 $ dnf history info <TRANSACTION>Replace
<TRANSACTION>with the ID from the first column, here2.dnf history infolists every package the transaction changed: undoing it reverses all of them. -
Undo the transaction:
dnfdowngrades the upgraded packages, removes packages the transaction installed and reinstalls ones it removed, and records the undo as a new transaction.
To go back one version of a single package instead, whatever transaction upgraded it, use dnf downgrade:
dnf list --showduplicates <PACKAGE> lists the versions the repositories offer; sudo dnf downgrade <PACKAGE>-<VERSION> installs a specific one.
If the package is the kernel, don't downgrade it: dnf keeps previous kernels installed (installonly_limit=3 in /etc/dnf/dnf.conf keeps three in total, including the newest), so choose an older one in the boot menu instead, as described in How to boot into rescue mode.
Arch's repositories only carry the current version of each package, so the older version has to come from your package cache or from the Arch Linux Archive.
Partial upgrades aren't supported
Arch packages are built against the current versions of each other. Downgrading one package can break it or packages that depend on it; downgrade its dependencies with it if the update changed them too, and upgrade again as soon as a fixed version is available.
-
Find the previous version in
/var/log/pacman.log: -
Look for that version in the package cache, which keeps every version
pacmandownloaded until you clean it: -
Install the older package file:
Packages built for every architecture end in
-any.pkg.tar.zstinstead of-x86_64.pkg.tar.zst.
If the cache no longer has the version (because of pacman -Sc, paccache or a new installation), install it from the Arch Linux Archive, which keeps every package Arch has published, signed as the original was.
Packages are under packages/<FIRST_LETTER>/<PACKAGE>/, where <FIRST_LETTER> is the first letter of the package name:
Gentoo keeps several versions of most packages in the ebuild repository, but removes old ones over time. If the version you want is still there, Portage can install it again, from a binary package when one is available and from source otherwise.
-
Find the version installed before the update with
qlop, which reads Portage's merge log (readable only by root and members of theportagegroup): -
Check that the repository still has an ebuild for it:
$ ls /var/db/repos/gentoo/<PACKAGE>/ Manifest metadata.xml tree-2.1.1-r1.ebuild tree-2.2.1.ebuild tree-2.3.2.ebuildIf it doesn't, the ebuild is still in the history of the Gentoo repository, and you can copy it into a local ebuild repository; that's beyond this guide.
-
Mask the versions newer than the one you want, so that the next
@worldupdate doesn't bring the update straight back.<NAME>is the package name without its category, heretree: -
Install the older version without adding a version to your
@worldset:--getbinpkguses Gentoo's binary package host when it has the version; binary packages you built yourself are used from/var/cache/binpkgswith--usepkg.
Verify¶
Check the installed version:
Then test the program, and restart any service that uses it.
Keep the update from coming back¶
Except on Gentoo, where the mask from step 3 already does this, the next upgrade installs the newer version again. Hold the package at the version you rolled back to, as described in How to hold a package at its current version, and release the hold once a fixed version is available.
Troubleshooting¶
E: Version '…' for '…' was not foundfromapt-get- No configured repository offers that version any more, and it isn't in
/var/cache/apt/archives/. On Debian, download the.debfiles from snapshot.debian.org and install them withsudo apt-get install ./<FILE>.deb, where<FILE>.debis the name of each downloaded file; on Ubuntu, older builds are listed on the package's Launchpad page. Packages were downgraded and -y was used without --allow-downgradesfromapt-getapt-getrefuses to downgrade unattended unless you say so. Add--allow-downgrades, after checking the list of packages without-y.dnf history undoreportsCannot find rpm nevraorNo package … available- One of the versions the transaction replaced is no longer in any enabled repository. Undo fewer packages with
dnf downgrade <PACKAGE>-<VERSION>, or find the old package in the distribution's vault (AlmaLinux and Rocky Linux publish older minor releases there). pacman -Ureportssignature from "…" is unknown trustorinvalid or corrupted package- The package keyring has changed since the old package was signed. Update
archlinux-keyringfirst (sudo pacman -Sy archlinux-keyringfollowed by a fullsudo pacman -Su), then try again. emergereportsthere are no ebuilds to satisfythe version- The ebuild has been removed from the Gentoo repository. Recover it from the repository's Git history into a local ebuild repository, or accept a version that's still available.
Related¶
- How-to: How to hold a package at its current version
- How-to: How to find which package provides a file
- How-to: How to add a third-party repository safely
- Reference: Package manager commands
- Reference: Repository configuration
- Explanation: How package management works
- Explanation: Binary and source distributions