apt upgrade installs newer versions of installed packages and never removes anything. If an upgrade would require removing a package, that upgrade is skipped. apt full-upgrade does the same job but may remove installed packages when needed to upgrade the system as a whole. It replaces the older dist-upgrade name.
What the manuals say
The apt manual describes upgrade as installing available upgrades, possibly installing new packages to satisfy dependencies, but never removing existing ones. The Debian Reference describes dist-upgrade as installing candidate versions while removing other packages if needed, and lists apt full-upgrade as its equivalent.
| Command | Installs new dependencies | Removes packages | Typical use |
|---|---|---|---|
| apt-get upgrade | Yes | Never | Routine updates |
| apt full-upgrade | Yes | If needed | Release upgrades, stuck updates |
The risk hidden in the safe command
Because upgrade skips anything that would need a removal, a security update can sit unapplied. You see a "kept back" message and move on. Packages are kept back for a few reasons, and one of them is harmless: Ubuntu's phased updates. Another is a real dependency conflict. Do not assume either way. See what are Ubuntu phased updates.
To find out why a package was kept back, ask apt directly:
apt list --upgradable
apt-cache policy package-name
apt-get -s full-upgrade
The last command simulates the full upgrade and prints what would be installed and removed, without doing it.
When full-upgrade is the right call
- Moving from one release to the next, where the Debian Reference recommends it.
- A package is kept back and the simulation shows only expected removals, for example an old library version replaced by a new one.
When to stop and read first
- The simulation removes something you installed on purpose, such as a database server or a runtime.
- A production host with no snapshot or rollback.
- Packages from third party repositories are involved, because their dependency choices may not match the distribution's.
A middle path for production
- Run the simulation and save the output.
- Compare removals against your expected list.
- Take a snapshot or confirm you can rebuild the host.
- Apply, then run a restart check, as in how to find services that need a restart after a library update.
For containers, none of this belongs on a running instance. Rebuild the image instead.
Reading the simulation output
A simulated run lists packages under headings such as upgraded, newly installed and removed. Scan the removed list first. Library packages with a version number in the name are often replaced by a newer one, which is expected. A server, a runtime or a tool you rely on appearing in that list is a reason to stop.
Also check for a large count of newly installed packages. That can happen when a metapackage pulls in new dependencies, and it increases what you have to keep patched.
A note for containers and CI
In a Dockerfile you usually do not need a full upgrade at all. Start from a current base image and install only the packages you need. Upgrading everything in a layer makes builds less repeatable and hides which change fixed which problem. Rebuild the base instead, as covered in should you run apt upgrade inside a container or rebuild.
Quick check
Is apt-get dist-upgrade the same as apt full-upgrade?
The Debian Reference lists apt full-upgrade as the equivalent of dist-upgrade.
Why does apt say some packages are kept back?
The cause varies: a dependency change that needs removal, a phased rollout on Ubuntu, or a hold you set. Check with apt-cache policy and a simulated run.
Safeguard tracks which of your packages and dependencies have known advisories, so a quietly kept back security update shows up as an open finding instead of a surprise.
Sources
Last reviewed: 19 October 2026.