Skip to main content
RunBook Academy

LinuxXI · Package ManagementVersion pinning

Package pinning, holds, and version selection

Intermediate⏱ ~10 minbashapt-markapt-cachednf

What you'll learn

  • Pin specific package versions in apt and dnf
  • Use hold and version operators to lock a version
  • Audit pinning state across the fleet
  • Decide when pinning is appropriate

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-09

Not yet marked complete on this device.

Production fleets pin package versions for stability: every host runs the same version of every critical package, regardless of what the repositories now offer. Version pinning is the discipline that prevents “every host upgraded to a different version on Friday and now we have N bugs”.

Pinning in apt

Configuration changeapt-mark hold
$ sudo apt-mark hold openssh-server; apt-mark showhold
openssh-server set on hold.
openssh-server

Illustrative output

Configuration changeapt preferences
$ sudo tee /etc/apt/preferences.d/no-default-jdk.pref >/dev/null <<EOF
Package: default-jdk
Pin: release o=Ubuntu
Pin-Priority: 50

Package: default-jdk
Pin: version 17.*
Pin-Priority: 999
EOF
sudo apt update
...

Illustrative output

The bands are documented in apt_preferences(5) and the boundaries matter — a pin of exactly 1000 does allow a downgrade, and 990 is the line between “prefer” and “default”, not 900:

Pin-PriorityEffect
P >= 1000Installed even if it is a downgrade
990 <= P < 1000Installed even if it does not come from the target release
500 <= P < 990Installed unless a version from the target release is available — the default band
100 <= P < 500Installed unless a version from some other distribution is available
0 < P < 100Installed only if no version of the package is installed
P < 0Never installed

The 0 < P < 100 band is the one operators reach for and the one most often missing from cheat sheets: it makes a repository available for a deliberate apt install foo/bar without ever letting apt upgrade pull from it.

Prove the pin took effect

A pin file that apt cannot parse is silently ignored — there is no error, the package just upgrades anyway. Never assume; ask:

apt-cache policy openssh-server   # candidate version and the pin that chose it
apt-cache policy                  # priority of every configured origin

If apt-cache policy <package> does not show your pin priority against the origin you pinned, the pin is not doing anything.

Pinning in dnf

Configuration changednf versionlock
$ sudo dnf install openssh-server-9.6p1-3.el9; sudo dnf versionlock add openssh-server; dnf versionlock list
...

Illustrative output

Configuration changeunlock
$ sudo dnf versionlock delete openssh-server; sudo dnf install openssh-server
...

Illustrative output

When to pin

Pin?Reason
YesProduction-critical service (sshd, sudo, systemd, openssl) where a regression would cause widespread impact
YesApplication with custom integration (a specific Java version, a specific Python version)
YesSecurity-sensitive package where you control the upgrade cycle
NoStandard libraries that the application does not depend on directly
NoPackages that you actively want to receive security updates for

Auditing pinning state across the fleet

Read-only / Safefleet audit
$ ansible all -m shell -a 'apt-mark showhold' 2>/dev/null | head
...

Illustrative output

Knowledge check

Knowledge check · 3 questions

  1. Q1. What does `apt-mark hold openssh-server` do?

  2. Q2. Pinning a package also blocks security updates for that package.

  3. Q3. Which of the following are correct pinning practices? Select all that apply.

Passing score: 75%. Answers are checked in this browser.