After an Ubuntu release upgrade, or when you disable a third-party repository, you can end up with obsolete packages: software that is still installed but no longer offered by any source in /etc/apt/sources.list and /etc/apt/sources.list.d/. The do-release-upgrade tool normally asks to remove them at the end; if that step was skipped—especially after a failed upgrade—you clean them up yourself with apt.
This guide shows how to list, preview, and remove obsolete packages on Ubuntu using APT 2.x filters (?obsolete, ~o). I ran the commands on Ubuntu 25.04 and kept real output so you can compare your machine.
Tested on: Ubuntu 25.04 (Plucky Puffin); kernel 6.14.0-37-generic; amd64.
apt autoremove) or orphaned (third-party tools). Skim the comparison table below before running a bulk remove—blind apt remove '?obsolete' can delete Docker, Slack, or old kernels you may still want.
Obsolete vs unused vs leftover config
| Term | What it means | Typical command |
|---|---|---|
| Obsolete | Installed version not in any configured apt repo (/now in apt list) |
apt list '?obsolete' |
| Auto-installed unused | Dependency nothing requires anymore | sudo apt autoremove |
| rc state | Package removed; config files left | dpkg -l | grep '^rc' then apt purge |
| Old kernels | Previous linux-image-* after updates |
sudo apt autoremove --purge (keep uname -r) |
| APT cache | Downloaded .deb files in /var/cache/apt/archives/ |
sudo apt clean / autoclean |
The Ubuntu Server package management and apt(8) manual document routine autoremove and clean; obsolete handling is the extra step after dist-upgrades described in Debian obsolete packages guidance.
When obsolete packages appear
Common situations:
do-release-upgradefinished (or almost finished) but the “Remove obsolete packages?” prompt never ran—often after you fixed the upgrade manually withsudo dpkg --configure -a.- A package was renamed or dropped in the new Ubuntu release (old name still installed).
- You installed a local
.deb(sudo apt install ./file.deb) and the file/version is gone from disk while the package remains. - A third-party repo is broken or removed, so installed packages show
[installed,local]even though you still rely on them.
Prerequisites
- Ubuntu with APT 2.0+ (22.04 LTS and newer; 25.04 tested).
sudofor remove/purge operations.- A finished or nearly finished upgrade if you are cleaning up after
do-release-upgrade—resolve broken dpkg state first.
Choose a cleanup path
| Goal | Jump to |
|---|---|
| See what apt considers obsolete | List obsolete packages |
| Remove one package safely | Method 1 |
| Remove all obsolete after review | Method 2 |
| Cleanup after failed release upgrade | Method 3 |
Purge leftover config (rc) only |
Method 4 |
| Related disk hygiene (not obsolete) | Related maintenance |
List obsolete packages
APT accepts the ?obsolete filter (and shorthand ~o):
apt list --installed '?obsolete'Equivalent shorthand:
apt list ~oOn Ubuntu 25.04 the start of that list looked like this:
WARNING: apt does not have a stable CLI interface. Use with caution in scripts.
Listing...
containerd.io/now 2.2.1-1~ubuntu.25.04~plucky amd64 [installed,local]
docker-ce/now 5:29.2.1-1~ubuntu.25.04~plucky amd64 [installed,local]
linux-image-6.14.0-33-generic/now 6.14.0-33.33 amd64 [installed,local]
slack-desktop/now 4.50.143 amd64 [installed,local]
...Read the line carefully:
/now— this exact version is not in your current apt indexes.[installed,local]— often a.debinstall or a repo that did not refresh (SSL error, disabled list).
Count how many lines you have (exclude the Listing... header):
apt list --installed '?obsolete' 2>/dev/null | grep -c '/now'Here that returned 15 packages—including Docker and an older kernel—not all of them are “leftovers from Ubuntu 24.04.” Review the list before bulk removal.
Optional: non-Ubuntu-origin packages
To see packages whose origin is not Ubuntu (includes active third-party repos):
apt list --installed '?not(?origin(ubuntu))'That can list Google Chrome, Docker, and PPA packages you still need. Do not treat this as the same as ?obsolete.
After do-release-upgrade: check the log
If you upgraded recently, the upgrader may have recorded intended removals:
sudo grep -i '^Obsolete:' /var/log/dist-upgrade/main.log | tail -1Use that line as a checklist alongside apt list '?obsolete'.
Method 1: Remove one obsolete package
When you recognize a single leftover (for example an old metapackage name):
sudo apt purge package-namepurge removes configuration files; remove keeps configs under /etc.
Preview what would happen:
sudo apt-get -s purge package-nameMethod 2: Remove all obsolete packages (bulk)
Always simulate first:
sudo apt-get -s -V remove '?obsolete'On Ubuntu 25.04 the simulation ended with lines like:
Remv docker-ce [5:29.2.1-1~ubuntu.25.04~plucky]
Remv linux-image-6.14.0-33-generic [6.14.0-33.33]
Remv slack-desktop [4.50.143]If that matches what you intend to delete:
sudo apt -V remove '?obsolete'APT prompts for confirmation unless you pass -y. The -V flag prints each package name as it is removed—useful in logs.
Then clear dependency debris:
sudo apt autoremove --purgesudo apt update before removing. They often show as obsolete when apt update cannot reach the vendor repo—not because the app itself is unwanted.
Method 3: After do-release-upgrade or failed upgrade
When the graphical or CLI upgrader stops before “Remove obsolete packages?”, run this sequence after you have a consistent system (sudo dpkg --configure -a and sudo apt -f install if needed):
1. Auto-remove unused dependencies and old kernels (safe baseline):
sudo apt update
sudo apt autoremove --purgeA simulated autoremove on the test host only offered libtorrent-rasterbar2.0—far fewer packages than a full obsolete sweep.
2. List and review obsolete packages:
apt list --installed '?obsolete'3. Remove obsolete packages you confirmed:
sudo apt-get -s -V remove '?obsolete'
sudo apt -V remove '?obsolete'4. Purge rc configuration leftovers (see Method 4).
5. Refresh boot menu after kernel cleanup:
sudo update-grubVerify you did not remove the running kernel:
uname -r
dpkg -l 'linux-image-*' | grep '^ii'The running kernel on the test system was 6.14.0-37-generic; 6.14.0-33 appeared as obsolete/local and would be removed by bulk ?obsolete—expected for an old kernel, but never remove the version matching uname -r.
Method 4: Purge rc configuration leftovers
Packages in rc state are already uninstalled; only config files remain:
dpkg -l | grep '^rc'Example lines:
rc apg 2.2.3.dfsg.1-7 amd64 Automated Password Generator
rc linux-image-6.14.0-15-generic 6.14.0-15.15 amd64 Signed kernel image genericThe test host had 26 rc entries. Purge them after review:
dpkg -l | awk '/^rc/{print $2}' | xargs -r sudo apt purge -yOr one package:
sudo apt purge apgThis is separate from obsolete binary packages but is part of the same post-upgrade housekeeping people ask about.
Related maintenance: autoremove, cache, kernels
These commands are not obsolete-package removal but appear in the same “clean my Ubuntu” searches. For unused dependency cleanup, cache hygiene, and rc config purges, see remove unused packages on Ubuntu.
# Unused dependencies
sudo apt autoremove --purge
# Drop downloaded .deb cache
sudo apt clean
# Drop only superseded .deb files still in cache
sudo apt autoclean
# Cache size check
du -sh /var/cache/apt/archives/For ongoing unattended cleanup of unused dependencies and kernel packages, see unattended-upgrades options Remove-Unused-Kernel-Packages and Remove-Unused-Dependencies in /etc/apt/apt.conf.d/50unattended-upgrades.
Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
Everything third-party shows ?obsolete |
apt update failed for external repos |
Fix SSL/proxy; sudo apt update; re-list before remove |
apt remove '?obsolete' wants to delete Docker/Slack |
[installed,local] while repo unreachable |
Restore vendor sources.list.d entry; update indexes |
autoremove removes almost nothing after upgrade |
Obsolete ≠ autoremove | Use ?obsolete list and dist-upgrade log |
| Removed obsolete app but configs remain | Used remove not purge |
sudo apt purge packagename or clear rc entries |
| Boot menu still lists old kernels | Kernels not purged | autoremove --purge after removing obsolete linux-image-* |
E: Unable to locate package on purge |
Package already gone (rc only) |
sudo dpkg --purge packagename |
References
- Remove unused packages on Ubuntu
- apt(8) — Ubuntu man page
- Package management — Ubuntu Server documentation
- Obsolete packages — Debian Wiki
- do-release-upgrade(8) — Ubuntu man page
- unattended-upgrade(8) — Ubuntu man page
Summary
On Ubuntu, obsolete packages are installed software whose version no longer exists in your apt sources—list them with apt list --installed '?obsolete', preview with sudo apt-get -s -V remove '?obsolete', then remove only what you have verified. That is the manual equivalent of the Remove obsolete packages? step in do-release-upgrade, which you may need after an interrupted release upgrade.
Do not confuse this with apt autoremove (unused dependencies) or apt clean (download cache). Purge rc configs separately, keep the kernel from uname -r, and fix broken third-party repos before bulk removal so you do not uninstall tools you still rely on.

