Controlling Ubuntu LTS Point-Release Updates with APT Pinning and Unattended-Upgrades
Learn how to combine APT pinning with unattended-upgrades to keep Ubuntu LTS servers stable while still receiving automatic security patches—without letting point releases override your pinned dependencies.
19 Sept 2025, 01:01 UTC

The Problem: Point Releases Can Override Your Pinned Dependencies
Ubuntu LTS point releases (for example 22.04.1, 22.04.3) ship updated package sets that APT treats as the new default candidate versions. If you have pinned a specific package version or origin to keep a production workload stable, a point release can silently promote newer versions that satisfy the pin's version constraint but introduce behavioral changes—updated libc, kernel ABI shifts, or Xorg server revisions—that break your application.
The default APT behavior prefers the highest version number from any enabled repository. When a point release lands, those higher versions become candidates and can be pulled in by a routine apt upgrade or by the unattended-upgrades daemon if its configuration is not explicitly restricted.
Thesis: Combine APT Pinning with Security-Only Unattended-Upgrades
You can keep the stability of a frozen package set while still receiving critical security patches by doing two things:
- Configure
unattended-upgradesto install only packages from the-securitypocket. - Create APT pin files that assign a high priority to the base LTS release (e.g.,
jammy) and a lower priority to point-release updates (jammy-updates,jammy-proposed).
This approach lets the daemon apply security fixes automatically, but prevents the point-release package versions from becoming the default upgrade candidates.
Step 1: Restrict Unattended-Upgrades to the Security Pocket
Edit /etc/apt/apt.conf.d/50unattended-upgrades (requires root). The key settings are the Allowed-Origins pattern and the package blacklist. A minimal security-only configuration looks like this:
Unattended-Upgrade::Allowed-Origins {
"${distro_id}:${distro_codename}-security";
};
Unattended-Upgrade::Package-Blacklist {
// Kernel and libc are often pinned separately; keep them out of auto-updates
"linux-image-generic";
"linux-headers-generic";
"libc6";
"libc6-dev";
};
Unattended-Upgrade::AutoFixInterruptedDpkg "true";
Unattended-Upgrade::MinimalSteps "true";
Unattended-Upgrade::InstallOnShutdown "false";
With this configuration, unattended-upgrades will only consider packages originating from ubuntu:jammy-security (or the equivalent for your release). The blacklist prevents automatic kernel or libc upgrades that could require a reboot or break ABI compatibility.
Step 2: Pin the Base Release and Deprioritize Point-Release Pockets
Create a pin file in /etc/apt/preferences.d/ (e.g., 99-lts-base-pin). The following example pins the base jammy release at priority 1000 (highest) and sets jammy-updates and jammy-proposed to 500, which is the default priority for installed packages. This means APT will prefer the base release versions unless a package is not present there.
Package: *
Pin: release n=jammy
Pin-Priority: 1000
Package: *
Pin: release n=jammy-updates
Pin-Priority: 500
Package: *
Pin: release n=jammy-proposed
Pin-Priority: 100
Package: *
Pin: release n=jammy-security
Pin-Priority: 1000
Notes:
Pin-Priority: 1000makes the base release and security pocket "always preferred" even over installed versions.500is the standard priority for installed packages;jammy-updateswill only be used if the package is absent fromjammyandjammy-security.100forproposedeffectively disables it unless explicitly requested withapt install -t jammy-proposed.
Worked Example: Verifying the Setup on a 22.04 Server
Assume you are on Ubuntu 22.04 (Jammy) and have applied the two configuration files above. Run the following commands as root or with sudo to confirm the behavior.
1. Check the candidate version for a critical package
apt policy libc6
Expected output shows the candidate version coming from jammy-security (priority 1000) or jammy (priority 1000), not from jammy-updates (priority 500). The *** marker indicates the selected candidate.
2. Simulate an unattended-upgrades run
unattended-upgrades --dry-run --debug
Review the output: only packages from the -security origin should be listed for installation. Kernel and libc packages should be absent because of the blacklist.
3. Inspect the automated update log
tail -n 50 /var/log/unattended-upgrades/unattended-upgrades.log
Confirm that recent entries show only security-marked packages (origin Ubuntu jammy-security) and that no jammy-updates packages were installed.
4. List all active pin rules
apt-cache policy
Cross-reference the printed priorities with your /etc/apt/preferences.d/ files to ensure no stray pin files (e.g., from third-party repos) are overriding your intended priorities.
Trade-Offs and Limitations
- Security gaps from aggressive pinning: If a security fix is only released in
jammy-updates(rare, but possible for non-kernel/user-space packages), your pin priority of 500 will not pull it automatically because the basejammyversion remains at 1000. You must monitor Ubuntu Security Notices and manually approve such updates. - Kernel and hardware enablement: The blacklist prevents automatic kernel upgrades. New hardware support (HWE kernels) and livepatches require manual tracking or an Ubuntu Pro subscription. Pinning the kernel at the base release version means you won't get newer drivers unless you explicitly install
linux-generic-hwe-22.04. - Snap packages are unaffected:
snapdmanages its own update channel independently of APT. If you rely on Snap applications, configure their refresh schedule separately (snap refresh --holdorsnap set system refresh.timer=...). - Manual intervention to break a freeze: If a misconfigured pin locks a package to an outdated version, you must run
apt-get full-upgrade(which respects pins but can install new dependencies) or temporarily adjust the pin priority to allow the upgrade.
Actionable Closing: Verify Monthly, Adjust Quarterly
Add a recurring task to your operations runbook:
- Monthly: run
unattended-upgrades --dry-run --debugand scan/var/log/unattended-upgrades/unattended-upgrades.logfor unexpected packages. - Quarterly: review Ubuntu Security Notices for any fixes released only in
-updates; if found, temporarily raise that pocket's priority for the affected package, upgrade, then restore the pin. - Annually: test a full
apt-get full-upgradein a staging environment to ensure the pin set does not create unresolvable dependency chains before the next LTS point release.
This discipline keeps your LTS servers on a predictable package baseline while still receiving the security patches that matter.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.