How to Configure APT Pinning in Ubuntu to Prioritise Repositories and Lock Package Versions

When managing Ubuntu servers and desktops, administrators often introduce third-party Personal Package Archives (PPAs), custom vendor repositories (such as Docker, NodeSource, or PostgreSQL), and official backports alongside standard Ubuntu archive mirrors. Without explicit package management rules, running apt upgrade automatically installs the highest numerical version found across all enabled sources, which can unintentionally overwrite custom-compiled binaries or pull unstable upstream packages. APT Pinning solves this challenge by allowing administrators to assign granular priority scores to specific repositories, packages, and version numbers.

Understanding APT Pin-Priority Values and Evaluation Rules

APT resolves package installation candidates using a numerical priority scoring system defined in the apt_preferences manual. When multiple versions of a package exist across your configured repository sources, APT selects the candidate with the highest Pin-Priority value:

  • P > 1000: Forces an installation or downgrade even if the targeted version is older than the currently installed build.
  • 990 <= P < 1000: Installs a target version even if it does not originate from the default release, provided no newer version is installed.
  • 500 <= P < 990 (Default): Standard priority for all official distribution repositories. The newest package version is installed automatically.
  • 100 <= P < 500: The target version is installed only if no other package version is available elsewhere. Common for backports repositories (typically assigned P=100).
  • 0 <= P < 100: The version will not be installed unless no version of the package is currently installed.
  • P < 0: Prevents the targeted package version or repository from ever being installed under any condition.

Configuring APT Preferences Files

While APT historically utilised a single /etc/apt/preferences file, modern Ubuntu systems recommend placing modular configuration files inside the /etc/apt/preferences.d/ directory:

  1. Open a terminal session on your Ubuntu machine.
  2. Create a new preference file using a text editor with administrative privileges:
    sudo nano /etc/apt/preferences.d/pinning-rules
  3. Each rule entry requires three core directives:
    Package: <package-name or wildcard>
    Pin: <version, release, or origin>
    Pin-Priority: <integer>

Pinning a Specific Package to a Precise Version

If an enterprise database or web service requires an exact build (for example, pinning nginx to version 1.24.0-1ubuntu1):

Package: nginx
Pin: version 1.24.0*
Pin-Priority: 1001

Assigning a priority of 1001 locks the package to version 1.24.0. Even if a general system upgrade introduces nginx 1.26 or newer, APT will hold or downgrade the binary to match your specified pin.

Prioritising Upstream Repositories and Backports

To enable Ubuntu Backports without having every package on your system upgrade to backport releases automatically:

  1. Open your preferences file and configure a repository release target:
    Package: *
    Pin: release a=noble-backports
    Pin-Priority: 100
  2. Specify an elevated priority only for the individual tool you wish to pull from backports (e.g., golang):
    Package: golang*
    Pin: release a=noble-backports
    Pin-Priority: 990

With this configuration, standard system packages ignore the backports repository, but any package matching golang* automatically tracks the newer backport builds.

Preventing Installation of Unwanted Packages

If you want to completely block a specific package or daemon from ever installing as a recommended dependency:

Package: package-to-block
Pin: release *
Pin-Priority: -1

Verifying Pinning Policies with apt-cache policy

Before executing updates, always verify how APT interprets your priority directives:

  1. Update your local package lists:
    sudo apt update
  2. Run the policy audit command against your target package:
    apt-cache policy nginx
  3. Review the output table:
    nginx:
      Installed: 1.24.0-1ubuntu1
      Candidate: 1.24.0-1ubuntu1
      Version table:
         1.26.1 500
            500 http://archive.ubuntu.com/ubuntu noble-updates/main amd64 Packages
     *** 1.24.0-1ubuntu1 1001
            100 /var/lib/dpkg/status
  4. Confirm that the Candidate version points to your pinned release rather than the higher-versioned update candidate.

Get the best tech tips delivered straight to your inbox.

Join thousands of readers mastering Apple, Google, Microsoft, and Linux.