skip to content

Package managers

The OS-level package managers that install software, resolve dependencies, and apply updates on a host. Interviewers ask because dependency resolution, repository trust, and version pinning are what stand between a reproducible server and a snowflake nobody dares reboot.

on this pageshow

explore

  • apt5 questions
  • dnf5 questions
  • yum3 questions
  • Snap4 questions

questions

17

On a Debian or Ubuntu server, `apt install curl` fails with "Unable to locate package curl", and on a different, rarely-touched box an install fails with a 404 while downloading the .deb. What does `apt update` actually do, and why do both failures go away once you run it?

level: juniorimportance: must knowfreq 78%

answer

  1. metadata, not software
  2. lists live under /var/lib/apt
  3. unknown name versus missing file
  4. the pool keeps only current versions
  5. update and install in one run

basics

~20 s

apt update refreshes the package index from every configured repository and installs nothing. With no index apt cannot resolve the package name at all; with a stale index it asks the mirror for a .deb the archive has already replaced, so the download 404s.

solid answer

~40 s

`apt update` contacts every repository configured in `/etc/apt/sources.list` and `/etc/apt/sources.list.d/`, downloads their signed release and `Packages` indexes, and caches them under `/var/lib/apt/lists/`. It never installs or upgrades anything — it only refreshes apt's picture of what exists and at which version. A minimal image or a cleaned apt cache has no index at all, so `apt install curl` prints `Unable to locate package curl`; that means *this box* knows of no such package, not that Debian lacks it. On a machine whose index is weeks old, the version it recorded may already have been superseded on the mirror, and Debian and Ubuntu pools keep only current versions, so fetching the recorded filename returns 404. That is why automation always runs the update and the install in the same invocation.

go deeper

for a junior

Be able to say plainly that apt update refreshes the package lists and installs nothing, and that install or upgrade is what changes the system. Knowing to run it first on a fresh machine is the expected reflex.

for a middle

Explain where the index is cached, what a Packages stanza contains, and why a stale Filename entry produces a 404 rather than an older version being installed. Distinguish "no index" from "outdated index" by the error text.

for a senior

Show that you treat index age as a diagnostic signal during an incident, and that you pair update with install in one invocation in provisioning so a cached or replayed step cannot install from a stale picture. Recognise clock skew and disabled components as separate causes.

for a principal

Own the fleet policy: which suites are enabled, how index freshness is guaranteed on machines that are rebuilt versus long-lived, and whether reproducibility needs a pinned snapshot mirror rather than a live archive that drops superseded versions underneath you.

## Two commands that sound alike On Debian and Ubuntu, `apt update` and `apt upgrade` do unrelated jobs. `update` refreshes metadata. `upgrade` changes installed software. Nothing on disk changes as a result of `apt update` except apt's own cached index — which is exactly why running it is cheap and why leaving it out breaks everything downstream. ## What the index actually is Each entry in `/etc/apt/sources.list`, or in a `.list` / deb822 `.sources` file under `/etc/apt/sources.list.d/`, names an archive URI, a suite (`bookworm`, `noble-updates`, …) and one or more components (`main`, `universe`, …). For each of those, `apt update` fetches the signed `InRelease` file and the compressed `Packages` index it points at, then stores the result under `/var/lib/apt/lists/`. A `Packages` index is a flat list of stanzas, one per available package version: ``` Package: curl Version: 8.5.0-2ubuntu10.6 Depends: libc6 (>= 2.38), libcurl4t64 (= 8.5.0-2ubuntu10.6) Filename: pool/main/c/curl/curl_8.5.0-2ubuntu10.6_amd64.deb ``` Everything apt decides — `apt search`, `apt show`, which version is the candidate, what the dependencies are, and above all the `Filename:` it will download — is answered out of that cached file. apt does not ask the mirror "what do you have?" at install time; it consults the copy it took the last time you ran `update`. ## Failure one: there is no index A freshly built minimal image, a debootstrapped root, or a machine where `/var/lib/apt/lists` was emptied has no stanzas to search. `apt install curl` then reports: ``` E: Unable to locate package curl ``` That message is routinely misread as "curl is not in Debian". It means only that no *currently known* index offers a package with that name. The same message appears for a genuinely different reason: the package lives in a component you never enabled — many Ubuntu packages sit in `universe`, and `contrib`/`non-free` are separate on Debian. If `apt update` alone does not fix it, the next question is which components are configured, not whether the package exists upstream. ## Failure two: the index is stale Debian and Ubuntu archives are not version museums. When `curl 8.5.0-2ubuntu10.6` supersedes `…10.5` in `noble-updates`, the older `.deb` is dropped from the pool. An index cached before that point still carries the old `Filename:`, so apt requests a path that no longer exists and you get: ``` E: Failed to fetch http://archive.ubuntu.com/ubuntu/pool/main/c/curl/curl_8.5.0-2ubuntu10.5_amd64.deb 404 Not Found ``` The fix is `apt update`, not `--fix-missing` and not switching mirrors. This is the single most common apt failure on long-lived boxes and inside build automation, and it is why the idiom is one shell invocation: ``` apt-get update && apt-get install -y curl ``` Splitting the two across steps that can be cached or replayed independently reintroduces exactly the staleness the pair exists to avoid. ## When `apt update` itself fails * **Clock skew.** If the machine's clock is behind, apt rejects the release metadata with `E: Release file for … is not valid yet`, and the repository is simply not updated. Fix the clock (NTP/chrony); do not reach for options that disable the check. * **A suite that no longer exists.** After a distribution release upgrade, or when a suite reaches end of life and moves to an archive host, the index URL itself 404s and apt reports that the repository has no Release file. * **A partial failure.** apt can finish with warnings when one of several sources failed, so a script that only checks the exit status can proceed on a half-refreshed index. Read the output, or fail the run explicitly when any source errored. ## What to run next After an update, `apt list --upgradable` shows what changed without touching anything, and `apt-get -s upgrade` simulates the transaction. The modification times under `/var/lib/apt/lists/` tell you how old the picture was before you refreshed it — a useful thing to note during an incident, because a box whose index is six months old has probably not been patched in six months either.

  • Does `apt update` ever change which packages are installed on the machine?
    No. It only rewrites the cached indexes under `/var/lib/apt/lists/` and reports how many packages are upgradable. On Ubuntu, `apt-daily.timer` runs it periodically in the background, which is why the counts in the MOTD move without anyone touching the box; the separate `apt-daily-upgrade.timer` and unattended-upgrades are what actually install things.
  • An `apt update` fails with "Release file for … is not valid yet". What is going on?
    The machine's clock is behind the archive's metadata timestamps, so apt treats the release file as not yet valid and refuses to use that repository. It is a clock problem, not a repository problem — check `timedatectl`, get NTP or chrony syncing, and re-run. Suppressing the validity check hides a skew that will also break TLS and log correlation.
  • How do you see what a fresh `apt update` would change without installing anything?
    `apt list --upgradable` lists each package with its installed and candidate versions. `apt-get -s upgrade` (or `-s full-upgrade`) simulates the whole transaction and prints the plan, including anything that would be held back, without touching dpkg. Both read the cached index only, so run them after the update.

saying these in an interview costs you the question

  • Thinks apt update also upgrades installed packages
  • Reads "Unable to locate package" as the package not existing in Debian
  • Assumes mirrors keep every historical .deb, so old indexes stay valid
  • Answers a 404 on a .deb with --fix-missing instead of updating
  • Believes apt queries the mirror live during install

context

open as a page

On a RHEL 8 or 9 host, `yum install httpd` still works even though the system's package manager is dnf. What is the `yum` command on such a host, and what happened to /etc/yum.conf and /etc/yum.repos.d?

level: juniorimportance: must knowfreq 62%

basics

~20 s

On RHEL 8 and 9 the yum command is a symlink to dnf-3, so running yum runs dnf. /etc/yum.conf is a symlink to /etc/dnf/dnf.conf, and /etc/yum.repos.d is still the directory dnf reads repository files from.

open as a page

On a Debian or Ubuntu host, what is the difference between `apt upgrade`, `apt full-upgrade` and `apt-get dist-upgrade`, and which of them is allowed to remove an installed package?

level: middleimportance: must knowfreq 62%

basics

~20 s

apt upgrade never removes an installed package; anything whose upgrade would require a removal is kept back. apt full-upgrade and apt-get dist-upgrade are the same command and may remove packages to resolve conflicts. apt-get upgrade is stricter still: it also refuses to add new packages.

open as a page

On a RHEL or Fedora host, a `dnf upgrade` run an hour ago has left a service broken. How do you find out exactly what that transaction changed, how do you reverse it, and what makes the reversal fail?

level: middleimportance: must knowfreq 64%

basics

~20 s

dnf records every transaction locally. dnf history lists them with IDs, dnf history info <id> shows every package the transaction added, removed or upgraded, and dnf history undo <id> reverses it — provided the older RPMs are still obtainable.

open as a page

A snap-installed application refuses to open a file under /mnt/data even though the file is world-readable and you can read it with `cat` as the same user. Why does snap's strict confinement block it, and how do you grant the access?

level: middleimportance: must knowfreq 50%

basics

~20 s

Strict snap confinement sandboxes the process with AppArmor and seccomp, so access depends on the interfaces the snap has connected rather than on Unix permissions. Paths under /mnt need the removable-media interface, which does not auto-connect; attach it with snap connect.

open as a page

You push a new build of a package to your internal RPM repository, but on a RHEL 9 client `dnf install` still offers yesterday's version. What are the likely causes, and how do you make dnf see the new build?

level: juniorimportance: should knowfreq 52%

basics

~20 s

dnf works from cached repository metadata rather than contacting the repo on every command, so the client is usually reading a stale index. Force a refresh with dnf --refresh install or dnf clean metadata, and confirm the repo is enabled and its metadata was regenerated.

open as a page

Snap channels are written like `latest/stable` and `18/candidate`. What do the two components mean, what are the four risk levels, and what does running `snap refresh --channel=18/stable <snapname>` actually change?

level: juniorimportance: should knowfreq 42%

basics

~20 s

A snap channel is track/risk. The track names a parallel version series, such as latest or 18; the risk is stable, candidate, beta or edge. Refreshing with --channel switches which series the snap follows and installs that channel's current revision.

open as a page

A provisioning run on Ubuntu logs the line "WARNING: apt does not have a stable CLI interface. Use with caution in scripts." after `apt install -y nginx`. What is that warning telling you, and what should the script use instead?

level: middleimportance: should knowfreq 45%

basics

~20 s

The apt front end is an end-user tool whose output format and defaults may change between releases, so scripts must not depend on it. Use apt-get and apt-cache instead: they have a stable, documented interface, and apt prints that warning whenever its output is not a terminal.

open as a page

An `apt install` on an Ubuntu server is interrupted partway through. Afterwards apt refuses to run at all, first with "Could not get lock /var/lib/dpkg/lock-frontend" and later reporting that a package is only half-configured. How do you diagnose and recover the box?

level: seniorimportance: should knowfreq 50%

basics

~20 s

Treat them as two separate problems. Find who holds the lock with lsof or fuser — usually unattended-upgrades — and wait or stop that service rather than deleting the lock file. Then fix the underlying failure and run dpkg --configure -a, followed by apt-get install -f if dependencies are still unsatisfied.

open as a page

On a RHEL 8 host, `dnf install nodejs` installs Node.js 10 but your application needs Node.js 20. Walk through how you inspect and switch the module stream with dnf, and explain why `dnf module reset` is usually part of it.

level: seniorimportance: should knowfreq 32%

basics

~20 s

RHEL 8 ships several runtime versions as module streams, and one is marked default. Inspect with dnf module list nodejs, then reset the module's stream selection, enable the stream you want, and sync the installed packages onto it — dnf module switch-to does all three.

open as a page

On a RHEL 9 host, `dnf upgrade` has installed patched openssl and glibc packages, but a scanner still reports the vulnerable versions in running processes. Why, and which dnf command tells you what to restart or whether to reboot?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Upgrading a package replaces files on disk; processes already running keep using the code they loaded at start-up, so they stay vulnerable until restarted. dnf needs-restarting lists those processes, -s maps them to systemd services, and -r says whether a reboot is recommended.

open as a page

A snap-packaged service on a server started failing immediately after snapd refreshed it to a new revision. How do you get it back onto the previous revision, and what happens to the service's data when you do?

level: seniorimportance: should knowfreq 31%

basics

~20 s

Run snap revert on the snap: snapd points the current symlink back at the previous revision, which is still on disk, with no download. Each revision owns its data directory, so anything written under the new revision stays there rather than migrating back.

open as a page

An old runbook written for RHEL 7 tells you to run `yum remove <pkg>` and then `yum update -y` on RHEL 8 servers, where yum is now dnf. Which of those invocations can behave differently than they did under the original yum, and why?

level: seniorimportance: should knowfreq 42%

basics

~20 s

Both can. RHEL 8 sets clean_requirements_on_remove=True, so a remove also takes now-unneeded dependencies with it, and best=True, so an upgrade that cannot reach the newest version fails the whole transaction instead of quietly skipping the package.

open as a page

On Fedora 41 and later the `dnf` command is DNF 5, while RHEL 9 still ships dnf 4. What changes for you as an operator, and what is most likely to break?

level: middleimportance: nice to knowfreq 24%

basics

~20 s

DNF 5 is a rewritten implementation on the libdnf5 stack, made the default dnf in Fedora 41. Everyday verbs and the .repo files are broadly unchanged; what breaks is automation built on dnf 4's Python API, its plugins, or its exact output format.

open as a page

On an Ubuntu server, `df -h` lists a dozen /dev/loopN filesystems mounted under /snap, every one of them reporting 100% used. What are those mounts, is the 100% a problem, and how do you get a readable df and find where snap disk usage really is?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

Those are the read-only squashfs images of installed snap revisions, each attached to a loop device and mounted under /snap. A read-only squashfs is packed exactly full, so 100% is normal and permanent. Filter them with df -h -x squashfs.

open as a page

A still-running CentOS 7 server fails every `yum install` with "Could not resolve host: mirrorlist.centos.org". Why did its repositories stop working, and how do you get yum installing packages from that box again?

level: middleimportance: nice to knowfreq 34%

basics

~20 s

CentOS Linux 7 reached end of life on 30 June 2024, so the mirrorlist service stopped answering for it and the mirrors were retired. The content was archived at vault.centos.org, so you disable the mirrorlist lines in /etc/yum.repos.d and set explicit baseurl values pointing at the vault.

open as a page

Two Ubuntu servers that were built from the same image both run `apt install nginx` and end up with different versions. Using `apt-cache policy`, how do you determine which repository a package's candidate version comes from and why apt picked it?

level: seniorimportance: nice to knowfreq 32%

basics

~20 s

Run apt-cache policy with the package name on both hosts. It prints the installed version, the candidate apt would install, and a version table listing each available version with its priority and origin repository, so you can see which source won and which sources differ between the machines.

open as a page