One careless pin in /etc/apt/preferences.d/ can quietly steer every upgrade on the machine, so build it small and test it. This guide gives you a narrow apt_preferences rule that favours one package version or release, a command that shows the result, and a simulation that catches mistakes before installation. Allow 10 to 15 minutes, plus time to understand the repositories you already have configured.
The examples use APT 2.8.3, installed on Ubuntu 24.04 with the noble repositories.
/etc/apt/preferences.d/ and doing a real install need elevated privileges, normally through sudo./etc/apt/preferences and fragments in /etc/apt/preferences.d/. Fragments are read in alphanumeric order and must have no extension or a pref extension. Their names may contain only letters, numbers, hyphens, underscores, and full stops.Warning: a file with another suffix is ignored. That is an easy trap when you save an editor backup beside a live policy.
Choose a real package and inspect its available versions before writing a rule. This example uses apt, but replace it with the package you actually need.
apt-cache policy apt
On the reference machine, the installed and candidate versions are both 2.8.3, with priority 500 from the configured Ubuntu sources. Your output may differ. Look for the version lines and their priorities rather than copying this machine's repository details.
This command answers a different question from pinning: it shows the policy APT has calculated. It does not change packages. Keep the output so you can compare it after adding a preference.
For a package-specific preference, create a fragment with a descriptive name. The following rule gives versions of apt beginning with 2.8. priority 501. It is deliberately only one point above the usual uninstalled-package priority of 500, so it demonstrates selection without creating a downgrade rule.
sudo install -d -m 0755 /etc/apt/preferences.d
sudo tee /etc/apt/preferences.d/apt-local.pref >/dev/null <<'EOF'
Explanation: Prefer the selected apt 2.8 versions
Package: apt
Pin: version 2.8.*
Pin-Priority: 501
EOF
The blank line separates records. Package names the binary package, Pin describes the version or release to match, and Pin-Priority supplies the preference. A version wildcard such as 2.8.* matches versions beginning with that text. The manpage also supports source-package names prefixed with src:, package globs, and regular expressions, but start with an exact package name unless you have a reason to widen the match.
Warning: do not use priority 0, because APT documents its behaviour as undefined. A priority of at least 1000 can permit a downgrade, so keep that range for a tested, intentional rollback policy. A negative priority prevents a matching version from being installed. These are strong controls and deserve a simulation before you leave them in place.
Run the same policy query again.
apt-cache policy apt
Checkpoint: a matching available version should now show priority 501. If it does not, stop here. Check the fragment name, its spelling, blank-line separation, the package name, and whether the configured repositories actually offer a matching version. APT may also print a notice when it ignores a badly named fragment.
Policy output is necessary but not sufficient. Ask APT to resolve an install without changing the system. The simulation is safe for an ordinary user.
apt-get -s install apt
Read the proposed version and the package changes. A simulation normally reports that it is only a simulation and will not install anything. It can still expose dependency changes caused by a pin. If the result proposes removals, an unexpected release, or a version you did not intend, do not run the real command. Remove or narrow the fragment, then repeat the policy check and simulation.
How priorities behave for a package that is not already installed:
These are selection rules, not guarantees that dependencies will be satisfiable.
To favour a whole archive, use a general record. This example prefers a release whose archive name is stable, but only use it when that release is present in your own sources and you understand the effect on every package.
Package: *
Pin: release a=stable
Pin-Priority: 900
Package: * is broad, and a record like this can affect upgrades across the system. Test it with apt-get -s upgrade, and consider testing a full resolver operation appropriate to your distribution before applying it. You can combine release properties with commas, such as release a=stable, v=12. The comma acts like an AND, so every condition must match.
Tip: do not confuse origin with the Origin: field in a repository's Release file. Pin: origin "example.org" matches a download host name. To match a vendor or distributor from Release metadata, use a release condition such as Pin: release o=Debian. When in doubt, inspect the policy output and the Release metadata rather than guessing.
If the preference produces an unwanted result, remove the fragment before attempting an upgrade.
Warning: this is a destructive change to configuration, so confirm the exact path first.
sudo rm /etc/apt/preferences.d/apt-local.pref
apt-cache policy apt
Removing the fragment restores the policy supplied by the remaining preferences and repository metadata; it does not automatically change an already installed package. If a real operation has already installed an unwanted version, review apt-cache policy apt, choose a known available version, and simulate an explicit install before making another change.
Recovery: a priority above 1000 can make downgrades possible, but a downgrade may break dependencies or data formats. Take a backup and follow the package's own recovery guidance first.
/etc/apt/preferences.d/.apt-cache policy PACKAGE shows the intended priority for the intended version.apt-get -s install PACKAGE or the relevant upgrade simulation proposes no surprising removals or releases.