Skip to content

Best Practices and Common Pitfalls of Package Management


Every individual tool and technique in this section works cleanly on its own. Real package management trouble tends to come from the same handful of recurring situations — mixing management approaches, interrupted operations, forgotten pins. This chapter consolidates the best practices scattered across this section and walks through the pitfalls that come up most often in genuine day-to-day administration.

Consolidated Best Practices

Prefer official, signed repositories over standalone package files. Every trust mechanism covered in this section — signature verification, the signed-by/gpgcheck settings — only protects you when you’re actually going through a repository. A .deb or .rpm handed to you directly bypasses all of it.

Keep manually-built software in /usr/local, never /usr. This is worth restating as the single most important habit for avoiding conflicts between what you’ve built yourself and what the package manager thinks it owns.

Always purge, not just remove, when you genuinely want something gone. apt remove/dpkg -r leaving configuration behind is a deliberate design choice worth respecting when you might reinstall — but reaching for it out of habit when you actually meant “get rid of this completely” is exactly how a system accumulates rc-state clutter over time.

Capture a package’s file list before removing it, covered in the removal chapter — once it’s gone, that information is gone with it.

Pin critical packages deliberately, and review your pins periodically. A forgotten apt-mark hold is exactly how a system ends up running a meaningfully outdated, unpatched version of something important without anyone noticing.

Never hand-edit the package database, and never manually delete a package-installed file. This deserves its own full explanation below, since it’s a genuinely common and genuinely damaging mistake.

Pitfall 1: Manually Deleting A Package-Managed File

This is worth walking through concretely, because the failure mode isn’t obvious until you’ve seen it. Say a configuration file installed by a package is deleted directly with rm, instead of going through the package manager:

sudo rm /etc/somepackage/config.conf

The file is gone from disk — but the package database still believes it exists, because nothing told dpkg/rpm about the deletion. This creates a genuine inconsistency: dpkg -L somepackage will still list a file that no longer exists, rpm -V somepackage will flag it as missing, and — worse — reinstalling or upgrading the package later may behave unpredictably, since the package manager’s assumptions about what’s currently on disk no longer match reality.

The correct way to remove a single file that a package owns is to remove the package, not the file directly — or, if the file is genuinely meant to stay gone while the rest of the package remains, to understand you’re deliberately creating exactly the kind of tracked-but-missing inconsistency rpm -V/dpkg -V are built to detect, and be prepared to explain it later if it shows up in an audit.

Pitfall 2: Dependency Conflicts

Occasionally, installing one package fails because it needs a version of a dependency that conflicts with what something else already installed requires — colloquially “dependency hell.” Diagnosing this means understanding why a conflict exists, not just that one does:

apt-cache policy libssl-dev

Shows every available version across configured repositories and which one would actually be selected — often revealing that two different repositories are offering genuinely incompatible versions of the same package.

dnf repoquery --deplist somepackage

Lists every dependency a package declares, along with which installed package currently satisfies each one — the RPM-side equivalent for tracing exactly where a conflict originates.

The actual fix is rarely a package-manager trick — it’s usually removing a conflicting third-party repository, or accepting that two pieces of software genuinely can’t coexist on the same system in their current versions without one of them being containerized or otherwise isolated.

Pitfall 3: An Interrupted Installation Leaves A Broken State

Covered briefly in the dpkg chapter, worth restating as a genuine, common real-world scenario: a system crash, a killed process, or simply running out of disk space mid-install can leave the package database in a partially-configured state.

sudo dpkg --configure -a

The standard Debian-side recovery step — resume whatever was interrupted. On the RPM side, a corrupted database itself (rarer, but possible after a genuinely abrupt failure) can be rebuilt directly:

sudo rpm --rebuilddb

Neither of these should be reached for casually — they’re specifically for recovering from an abnormal interruption, not a routine step in normal operation.

Pitfall 4: A Repository’s Signing Key Has Expired Or Changed

sudo apt update
W: GPG error: ... NO_PUBKEY 1234ABCD5678EFGH

This is apt correctly refusing to trust metadata it can no longer verify — exactly the protection mechanism from earlier in this section doing its job, not a bug to route around by disabling signature checks. The correct fix is fetching the updated key from the repository maintainer through whatever legitimate channel they publish it, then retrying — never disabling gpgcheck or ignoring the warning as a shortcut.

Pitfall 5: Running Out Of Disk Space Mid-Install

A package installation failing partway through because the filesystem ran out of space during the download or unpack step is a genuinely common real-world failure, and it’s exactly the kind of situation dpkg --configure -a/rpm --rebuilddb above may be needed to recover from afterward — checking available space with df -h before a large install, particularly on a system already running low, is a cheap habit that avoids the problem entirely rather than needing to recover from it after the fact.

A Real Debugging Walkthrough: “This Package Won’t Install, And I Don’t Know Why”

Putting several of this chapter’s tools together in sequence, roughly the order worth trying in practice:

sudo apt install somepackage

Read the actual error message first — it’s often more specific than it initially appears.

apt-cache policy somepackage

Confirm which version(s) are actually available and from which repository.

sudo apt update

Rule out stale metadata as the cause before investigating further.

sudo dpkg --configure -a

Rule out a leftover interrupted state from a previous, unrelated operation.

apt-get install -f

Attempts to resolve broken dependencies directly — genuinely worth trying before assuming a deeper conflict.

Working through these roughly in order, rather than jumping straight to more invasive fixes, resolves the large majority of real “why won’t this install” situations without needing to guess.

What’s Next

With best practices and common pitfalls consolidated, this section has one chapter left — and it’s the one that closes it out properly: signing and distributing your own packages, taking the hello-tool examples built earlier in this section from “installable on this one machine” to something genuinely shareable and verifiable, the way real Ubuntu packages are.

Last updated on