Tools: Essential Guide: Stop Letting `apt autoremove` Surprise You: Practical `apt-mark` for Debian and Ubuntu

Tools: Essential Guide: Stop Letting `apt autoremove` Surprise You: Practical `apt-mark` for Debian and Ubuntu

Stop Letting apt autoremove Surprise You: Practical apt-mark for Debian and Ubuntu

What apt-mark actually controls

Why this matters in real life

Inspect your current package state

Show manually installed packages

Show automatically installed packages

Preview what autoremove would do

Protect a package from future autoremove

Tell APT a package is fair game for cleanup

A safe cleanup workflow

1. Review the candidate list

2. Rescue anything you want to keep

3. Re-run the simulation

4. Only then do the real cleanup

A practical example: cleaning up after a temporary install

Metapackages and minimize-manual

Where APT stores this state

What apt-mark is not

My practical rules

References apt autoremove is useful, but a lot of Linux admins treat it a little like a haunted button. You know it is supposed to remove packages that were installed only as dependencies and are no longer needed. But after enough package churn, desktop experiments, and one-off installs, it becomes easy to wonder: The answer is usually not guesswork. It is apt-mark. This article is a practical guide to the package state APT uses behind the scenes, how manual and auto marks affect autoremove, and a safe workflow for cleanup. When you explicitly install a package, APT marks it as manually installed. When APT installs extra packages only to satisfy dependencies, it marks those as automatically installed. According to the apt-mark(8) manual, once an automatically installed package is no longer depended on by any manually installed package, it is considered no longer needed and tools like apt-get autoremove will suggest removing it. That is the key model: A few common situations break the simple mental model: apt-mark is the tool for all four. Start by seeing what APT believes. If you want to check one package directly, filter it: If the package appears in showmanual, APT will not consider it removable just because it became a leaf dependency. Before changing anything, simulate the cleanup: The -s flag runs a simulation, which is the safest first check before any cleanup. On my host, a dry run currently reports no removals: That is boring, which is exactly what you want from a safe preview. If there is a package you want to keep even if nothing else depends on it, mark it as manual: APT will treat it as explicitly desired from that point forward. This is especially useful for: You can verify the change immediately: If you installed something temporarily and want APT to remove it later when nothing needs it, mark it as automatic: That does not instantly remove the package. It only changes its state. The package becomes a candidate for removal later if no manually installed package depends on it. Then preview the result: If the plan looks correct, run the real cleanup: Or, if you also want old config files purged: Here is the workflow I trust on Debian and Ubuntu systems: If a package appears in the simulated removal list but you actually want it: This avoids the two usual mistakes: cleaning blindly, or never cleaning at all. Imagine you temporarily installed a package for a task, and now you want the system to forget it unless something else still needs it. Check whether APT now sees it as auto-installed: If nothing manual depends on it anymore, a future autoremove can clean it up. Per the apt-mark(8) manual, this marks transitive dependencies of metapackages as automatically installed. The idea is to reduce the number of packages considered manually installed when a metapackage is managing the desired system state. This is useful, but it is not where I would start unless you already understand how your system was built, especially on servers with long upgrade histories or desktops with a lot of role changes. For most people, reviewing autoremove with a simulation and using targeted manual or auto marks is the safer first move. apt-mark(8) documents the auto-installed package state in: You usually should not edit that file directly. But it is useful to know this state is explicit and tracked, not magic. A quick boundary check helps avoid confusion: If your goal is version preference across repositories, that is an apt_preferences problem, not an apt-mark problem. These have held up well for me: apt autoremove stops feeling risky once you realize it is mostly a reflection of package state, and package state is something you can inspect and control. Templates let you quickly answer FAQs or store snippets for re-use. Hide child comments as well For further actions, you may consider blocking this person and/or reporting abuse

Command

Copy

$ -weight: 500;">apt-mark showmanual -weight: 500;">apt-mark showmanual -weight: 500;">apt-mark showmanual -weight: 500;">apt-mark showauto -weight: 500;">apt-mark showauto -weight: 500;">apt-mark showauto -weight: 500;">apt-mark showmanual | grep '^-weight: 500;">curl$' -weight: 500;">apt-mark showauto | grep '^-weight: 500;">curl$' -weight: 500;">apt-mark showmanual | grep '^-weight: 500;">curl$' -weight: 500;">apt-mark showauto | grep '^-weight: 500;">curl$' -weight: 500;">apt-mark showmanual | grep '^-weight: 500;">curl$' -weight: 500;">apt-mark showauto | grep '^-weight: 500;">curl$' -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove NOTE: This is only a simulation! Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to -weight: 500;">remove and 2 not upgraded. NOTE: This is only a simulation! Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to -weight: 500;">remove and 2 not upgraded. NOTE: This is only a simulation! Reading package lists... Building dependency tree... Reading state information... 0 upgraded, 0 newly installed, 0 to -weight: 500;">remove and 2 not upgraded. -weight: 600;">sudo -weight: 500;">apt-mark manual tmux -weight: 600;">sudo -weight: 500;">apt-mark manual tmux -weight: 600;">sudo -weight: 500;">apt-mark manual tmux -weight: 500;">apt-mark showmanual | grep '^tmux$' -weight: 500;">apt-mark showmanual | grep '^tmux$' -weight: 500;">apt-mark showmanual | grep '^tmux$' -weight: 600;">sudo -weight: 500;">apt-mark auto imagemagick -weight: 600;">sudo -weight: 500;">apt-mark auto imagemagick -weight: 600;">sudo -weight: 500;">apt-mark auto imagemagick -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get autoremove -weight: 600;">sudo -weight: 500;">apt-get autoremove -weight: 600;">sudo -weight: 500;">apt-get autoremove -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-mark manual PACKAGE_NAME -weight: 600;">sudo -weight: 500;">apt-mark manual PACKAGE_NAME -weight: 600;">sudo -weight: 500;">apt-mark manual PACKAGE_NAME -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get -s autoremove -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-get autoremove --purge -weight: 600;">sudo -weight: 500;">apt-mark auto jq -weight: 600;">sudo -weight: 500;">apt-mark auto jq -weight: 600;">sudo -weight: 500;">apt-mark auto jq -weight: 500;">apt-mark showauto | grep '^jq$' -weight: 500;">apt-mark showauto | grep '^jq$' -weight: 500;">apt-mark showauto | grep '^jq$' -weight: 600;">sudo -weight: 500;">apt-mark minimize-manual -weight: 600;">sudo -weight: 500;">apt-mark minimize-manual -weight: 600;">sudo -weight: 500;">apt-mark minimize-manual /var/lib/-weight: 500;">apt/extended_states /var/lib/-weight: 500;">apt/extended_states /var/lib/-weight: 500;">apt/extended_states - Why is APT trying to -weight: 500;">remove that package? - Why is this dependency still hanging around? - How do I keep a package I care about from getting swept up later? - manual means “keep this unless I -weight: 500;">remove it myself” - auto means “this exists to support something else, so -weight: 500;">remove it when nothing manual needs it” - You installed a package long ago as a dependency, but now you actually want to keep it. - You installed a metapackage, then later removed it, leaving behind a pile of dependencies. - You used a package temporarily for testing and want APT to clean it up naturally later. - You are afraid to run autoremove because you are not sure whether package state still reflects reality. - CLI tools you use directly - troubleshooting packages installed during incident response - libraries or helpers you intentionally keep for local scripts - desktop utilities that were originally pulled in indirectly - -weight: 500;">apt-mark manual/auto controls package -weight: 500;">install state used by autoremove - -weight: 500;">apt-mark hold prevents upgrades, installs, or removals for a package - -weight: 500;">apt-mark manual is not the same thing as pinning a package version - -weight: 500;">apt-mark auto is not immediate removal - Always simulate autoremove first. - Mark tools you use directly as manual. - Mark truly temporary packages as auto after the task is done. - Treat big desktop or metapackage cleanup carefully. - Use --purge only when you are comfortable losing leftover config files too. - Debian manpage, -weight: 500;">apt-mark(8): https://manpages.debian.org/bookworm/-weight: 500;">apt/-weight: 500;">apt-mark.8.en.html - Debian manpage, -weight: 500;">apt-get(8): https://manpages.debian.org/bookworm/-weight: 500;">apt/-weight: 500;">apt-get.8.en.html - Debian manpage, -weight: 500;">apt(8): https://manpages.debian.org/trixie/-weight: 500;">apt/-weight: 500;">apt.8.en.html