How Linux Handles Package Holding and Pinning

Linux distributions rely on package managers to maintain system software, typically prioritizing the installation of the latest available versions during updates. However, specific use cases—such as maintaining application compatibility, preventing regressions, or preserving custom configurations—require freezing software at designated versions. Linux handles this through mechanisms known as package holding, locking, and pinning, which instruct the dependency solver to ignore upstream updates for targeted software. This guide covers how these mechanisms function across major package management systems, including APT, DNF/YUM, and Pacman.


The Underlying Mechanism

When an administrator runs an upgrade command, the package manager queries remote repositories, compares the version numbers of installed packages against upstream candidates, and builds a dependency resolution graph.

Package holding and pinning intercept this process:


Debian, Ubuntu, and Derivatives (APT)

APT provides two primary approaches: quick state-based holding via apt-mark, and granular priority-based control via APT preferences.

1. State-Based Holding with apt-mark

The apt-mark utility changes the metadata state of an installed package directly in the /var/lib/dpkg/status or APT internal state files.

2. Advanced Pinning with APT Preferences

For complex scenarios—such as tracking a package from a specific release branch or pinning an exact version pattern—APT uses configuration files in /etc/apt/preferences or /etc/apt/preferences.d/.

A configuration block defines the target package, the pin rule, and a numerical priority:

Package: nginx
Pin: version 1.18.*
Pin-Priority: 1001

Understanding Pin-Priority values:


RHEL, Fedora, and CentOS (DNF and YUM)

Modern Red Hat-based distributions use DNF (or the legacy YUM), which manages package retention through the versionlock plugin or global configuration files.

1. The Versionlock Plugin

The versionlock plugin takes a snapshot of the package's exact epoch, version, release, and architecture, storing it in /etc/dnf/plugins/versionlock.list.

2. Configuration Exclusion

For simpler restrictions without installing plugins, packages can be excluded directly in /etc/dnf/dnf.conf:

[main]
exclude=kernel* mariadb*

This blocks DNF from calculating updates or dependencies for any package matching the defined globs.


Arch Linux (Pacman)

Arch Linux avoids complex priority scoring and handles package locks through directives in /etc/pacman.conf.

Using IgnorePkg and IgnoreGroup

Open /etc/pacman.conf and locate the [options] section:

When running pacman -Syu, the package manager explicitly prompts the user if it encounters an update for a package listed under IgnorePkg, defaulting to skipping the upgrade unless explicitly overridden by the operator.


openSUSE and SUSE Linux Enterprise (Zypper)

Zypper features native locking capabilities managed through its transaction engine.

Zypper stores these locks in /etc/zypp/locks, preventing automatic installation, update, or removal during transaction resolution.


Handling Dependency Conflicts on Held Packages

When a locked package is a dependency of another package marked for upgrade, the package manager faces a conflict:

  1. APT: Refuses to upgrade the dependent package, reporting that it has been "kept back."
  2. DNF: Aborts the transaction and outputs a broken dependency warning unless --nobest or --skip-broken flags are supplied.
  3. Pacman: Alerts the user to an unresolvable dependency loop, requiring manual user intervention to proceed.

To preserve system stability, package locks should be audited regularly to ensure that critical security patches are not unintentionally withheld.