The Cache has broken packages, exiting message is one of those Debian and
Ubuntu package manager errors that looks vague until you remember how many
moving parts are involved. apt has repository metadata, downloaded package
archives, dependency resolution, and a dpkg database underneath it. When one of
those layers is out of sync, a routine cron job, apt update, or
apt-get dist-upgrade can stop with a complaint about broken packages.
The fix is not to throw commands at the machine until one sticks. The right move is to figure out which layer is broken, then make the smallest repair that lets the package manager finish its work.
This article walks through the order I use on Ubuntu and Debian systems: inspect
the actual package state, refresh apt metadata, let apt repair dependencies when
it can, reconfigure unpacked packages with dpkg, and only then reach for manual
package removal. The full /boot case deserves special attention because it is
common on older Ubuntu servers and it can make the obvious fix fail.
What The Error Usually Means
apt is the dependency solver and repository-aware front end. dpkg is the
lower-level tool that actually unpacks, configures, removes, and purges Debian
packages. When apt says the cache has broken packages, it usually means one of
these things is true:
- The package lists in
/var/lib/apt/lists/are stale or inconsistent with the configured repositories. - A package was unpacked but not configured, often because an install or upgrade was interrupted.
- Dependencies cannot be satisfied with the currently enabled repositories.
- A package was installed from a repository that is no longer enabled.
- The local archive cache in
/var/cache/apt/archives/contains stale downloads. - The system ran out of space while installing a kernel or another large package.
That last one is easy to miss. Years ago I hit this on an older Ubuntu 12.04
server that had a tiny 256 MB /boot partition. apt-get clean was not enough,
because the package database wanted to finish a kernel upgrade before it would
allow ordinary package removal. The machine had a dependency problem, but the
root cause was boring: /boot was full.
Start With The Error, Not The Guess
Before changing anything, capture the real failure. Run the operation again and look for the first package-specific error, not just the final summary.
sudo apt update
sudo apt -f install
On older systems you may see the same pattern with apt-get:
sudo apt-get update
sudo apt-get -f install
The -f option is short for --fix-broken. It asks apt to correct a system
with broken dependencies in place. That does not mean apt can magically repair
every possible package database problem. It means apt is allowed to deduce an
install or remove plan that gets the dependency graph back to a consistent
state.
Read that plan before accepting it. If apt wants to remove an essential package, a desktop environment, a database server, or half the machine, stop. You are no longer in "quick repair" territory.
For a less invasive first look, use simulation mode:
sudo apt-get -s -f install
Simulation mode is useful on production-ish systems because it shows what apt would try to configure, install, or remove without making the change. It is not a substitute for a backup, but it is a nice speed bump before doing something exciting in the wrong direction.
Refresh Apt Metadata And Clear Stale Downloads
If the package lists are stale, start with the boring repair:
sudo apt update
If you see repository errors here, fix those first. A disabled PPA, an old release codename, an expired third-party repository, or a mismatched Debian suite can all produce dependency failures later. Check the files under:
/etc/apt/sources.list
/etc/apt/sources.list.d/
After the repository list is sane, clear downloaded package archives:
sudo apt clean
apt clean removes retrieved package files from the local archive cache. It is
not a dependency fix by itself. It helps when apt downloaded a package before a
repository changed, when a cached .deb is stale, or when disk space pressure is
part of the problem.
Then retry:
sudo apt update
sudo apt -f install
If that works, finish with the normal maintenance command:
sudo apt upgrade
Use full-upgrade or dist-upgrade deliberately. Those commands are allowed to
make larger dependency-resolution moves, including removals when needed. That is
often the right thing during release transitions, but it should not be muscle
memory on a machine you care about.
Reconfigure Packages That Were Unpacked But Not Configured
If an upgrade was interrupted, dpkg may have packages sitting in an unpacked state. Ask dpkg to finish configuring anything pending:
sudo dpkg --configure -a
That command configures packages that have been unpacked but not configured. It is the right next step when the system lost power, a maintainer script failed, a terminal session died, or an unattended upgrade was interrupted.
After dpkg has had a chance to finish, return to apt:
sudo apt -f install
sudo apt upgrade
This apt/dpkg back-and-forth is normal. dpkg fixes local package state. apt then uses repository metadata and dependency solving to finish the higher-level transaction.
Check For A Full Filesystem
Do not skip disk space. Package failures caused by full filesystems often masquerade as dependency failures because the package manager got stuck halfway through an install.
Check the obvious locations:
df -h /
df -h /boot
df -h /var
If /var is full, apt may not be able to store package lists or downloaded
archives. If /boot is full, kernel upgrades can fail after a new kernel package
is partly installed. That is where the repair gets less tidy.
On systems with a separate /boot, list installed kernels and compare them with
the running kernel:
uname -r
dpkg -l 'linux-image*' | grep '^ii'
Do not remove the kernel returned by uname -r. I usually keep the current
kernel and at least one known-good previous kernel. Removing every fallback
kernel is how a small maintenance task turns into a rescue-console afternoon.
If the package manager is still healthy enough, prefer apt:
sudo apt autoremove --purge
On Ubuntu systems with old kernels marked as automatically installed, this often does the right thing and keeps fallback kernels according to apt's kernel retention rules.
If apt cannot run because the dependency state is already broken, you may need to purge one old kernel package directly with dpkg to create enough room for apt to finish:
sudo dpkg --purge linux-image-OLD-VERSION-generic
On some Ubuntu releases you may also need the matching extra/modules and headers packages for that same old version:
sudo dpkg --purge linux-image-OLD-VERSION-generic linux-modules-OLD-VERSION-generic
sudo dpkg --purge linux-headers-OLD-VERSION linux-headers-OLD-VERSION-generic
This is the part where precision matters. Replace OLD-VERSION with an actual
old kernel version that is not running. Do not use a wildcard with dpkg --purge
unless you are completely sure what the shell will expand. The package manager
will do exactly what you asked, not what you meant.
Once /boot has room again, return to the normal repair path:
sudo apt -f install
sudo dpkg --configure -a
sudo apt autoremove --purge
sudo apt upgrade
The goal is not to keep using dpkg manually. The goal is to clear just enough space or state for apt to become useful again.
Identify Held Or Mismatched Packages
If disk space is fine and dpkg --configure -a does not clear the problem, look
for held packages and version mismatches.
apt-mark showhold
apt list --upgradable
apt-cache policy PACKAGE_NAME
Holds are not bad. They are often intentional on servers. But a held package can block a dependency chain when other packages move forward.
For a specific broken package, inspect what apt thinks is available:
apt-cache policy PACKAGE_NAME
That output tells you which version is installed, which version is the candidate, and which repositories provide it. If the installed package came from a PPA or third-party repository that is no longer enabled, apt may be unable to satisfy dependencies until you either restore the repository, downgrade to the distro package, or remove the package.
This is also where mixed-release systems bite people. A Debian stable machine with random testing packages, or an Ubuntu LTS host with a repository for the wrong codename, can produce broken-package errors that no amount of cache cleaning will fix.
When To Remove A Problem Package
Package removal is sometimes correct, but it should be a decision rather than a reflex. First simulate it:
sudo apt-get -s remove PACKAGE_NAME
If the removal plan is narrow and reasonable, then remove or purge it:
sudo apt remove PACKAGE_NAME
Use purge when you also want configuration files removed:
sudo apt purge PACKAGE_NAME
For packages that are only half-installed and blocking dpkg, direct dpkg removal can be necessary:
sudo dpkg --remove PACKAGE_NAME
or, when configuration files should go too:
sudo dpkg --purge PACKAGE_NAME
The tradeoff is simple: apt understands repositories and dependencies; dpkg understands local package state. Prefer apt when apt is still able to calculate a reasonable plan. Use dpkg when apt is stuck behind a local package database problem you can identify clearly.
A Practical Recovery Order
Here is the sequence I would use on most Debian or Ubuntu systems:
sudo apt update
sudo apt-get -s -f install
sudo apt -f install
sudo dpkg --configure -a
df -h / /boot /var
apt-mark showhold
sudo apt autoremove --purge
sudo apt upgrade
That is not a single paste-and-pray script. Treat it as a checklist. Stop when you see a concrete error, and let that error determine the next command.
For servers, I also want the basics before touching packages: a recent backup, a rollback plan, and some idea of what services are supposed to be running after the upgrade. The same practical caution applies to broader Linux operations; a small command can have large blast radius when it runs as root. I wrote about that kind of operational care in Resolving Hard Links Issues in Rsync Backups on Mac OS X and OpenSSH: Using a Bastion Host.
What I Would Not Do
I would not start by deleting files from /var/lib/dpkg/ or hand-editing dpkg's
status database. Those are last-resort recovery moves, not normal maintenance.
If you are at that point, slow down and make a copy of the relevant files before
touching them.
I would not blindly run commands copied from an old forum post that remove every
package matching linux-image-*. Kernel cleanup is a good idea. Removing the
running kernel or every fallback kernel is not.
I would not use --force options just to get past the current error. Force
options can be appropriate in narrow recovery work, but they are also a good way
to convert one understandable package problem into a stranger one.
The Bottom Line
The Cache has broken packages, exiting error is usually recoverable, but it is
not one single problem. Sometimes the fix is as simple as apt update followed
by apt -f install. Sometimes dpkg needs to finish configuring packages. And on
older Ubuntu systems with small /boot partitions, the real fix may be freeing
enough kernel space for apt to complete the upgrade it already started.
Work from evidence. Read the package names in the error. Check disk space. Use apt while apt can still reason about dependencies, and use dpkg only when you need to repair local package state directly. That discipline is what gets the machine back to boring, which is exactly where package management belongs.
For more practical systems troubleshooting notes, visit Slaptijack.