Skip to content

Package Version Locking

In production environments, certain critical packages must be pinned to specific versions to avoid compatibility issues from automatic updates. dnf-plugin-versionlock provides precise version locking capabilities.

Install the dnf versionlock plugin
dnf install -y dnf-plugin-versionlock
Confirm the plugin is installed
dnf versionlock --help
Lock the currently installed version
dnf versionlock add nginx
Lock to an exact version
dnf versionlock add nginx-1.20.1-14.el9
Lock all php-related packages
dnf versionlock add php-*
List all current version locks
dnf versionlock list
Remove the version lock for a specific package
dnf versionlock delete nginx
Remove all version locks
dnf versionlock clear

Prevent automatic kernel upgrades, suitable for environments with strict hardware driver compatibility requirements.

Lock the current kernel version
dnf versionlock add kernel
dnf versionlock add kernel-core
dnf versionlock add kernel-modules
dnf versionlock add kernel-modules-core

Verify the lock is in effect:

Confirm the kernel is locked
dnf check-update kernel
# Even if a new version exists, it will not appear

Production database upgrades require thorough testing first.

Lock PostgreSQL version
dnf versionlock add postgresql-server
dnf versionlock add postgresql
dnf versionlock add postgresql-libs
Lock MySQL/MariaDB version
dnf versionlock add mariadb-server
dnf versionlock add mariadb
dnf versionlock add mariadb-common
Lock Nginx and its modules
dnf versionlock add nginx
dnf versionlock add nginx-mod-*
Lock Apache version
dnf versionlock add httpd
dnf versionlock add httpd-core
dnf versionlock add mod_ssl
Lock PHP and its extensions
dnf versionlock add php php-cli php-common php-fpm php-mysqlnd php-pdo
Lock Node.js version
dnf versionlock add nodejs
dnf versionlock add npm
View the versionlock configuration file
cat /etc/dnf/plugins/versionlock.list
Directly edit the lock list
vi /etc/dnf/plugins/versionlock.list

The file format is one NEVRA (Name-Epoch:Version-Release.Arch) entry per line:

nginx-1:1.20.1-14.el9.x86_64
Back up the versionlock configuration
cp /etc/dnf/plugins/versionlock.list /root/versionlock-backup.list
Restore the versionlock configuration
cp /root/versionlock-backup.list /etc/dnf/plugins/versionlock.list

Package Exclusion (Alternative to versionlock)

Section titled “Package Exclusion (Alternative to versionlock)”

In addition to versionlock, you can use exclude to block specific packages from updating.

Globally exclude kernel updates
echo "exclude=kernel* kernel-core*" >> /etc/dnf/dnf.conf
Exclude specific packages in the BaseOS repo
dnf config-manager --save --setopt=baseos.exclude="kernel*"
Featureversionlockexclude
Pin to specific versionYesNo (blocks entirely)
Allows downgradeNoNo
Package-level controlExact NEVRAWildcards
Configuration locationSeparate filednf.conf or repo files

Use this when a locked package was accidentally updated or you need to revert an operation.

List recent dnf transactions
dnf history list --reverse
View which packages a transaction installed/updated
dnf history info <transaction-ID>
Undo a specific update transaction
dnf history undo <transaction-ID> -y
Re-execute a previously undone transaction
dnf history redo <transaction-ID> -y
Batch lock critical production packages
#!/bin/bash
# Define the list of packages to lock
LOCKED_PACKAGES=(
"kernel"
"kernel-core"
"kernel-modules"
"postgresql-server"
"postgresql"
"nginx"
"php"
"php-fpm"
"php-cli"
)
for pkg in "${LOCKED_PACKAGES[@]}"; do
echo "Locking: $pkg"
dnf versionlock add "$pkg" 2>/dev/null
done
echo "=== Current lock list ==="
dnf versionlock list
Check if locked packages have available updates
#!/bin/bash
echo "=== Version Lock Audit Report ==="
echo "Date: $(date)"
echo ""
# Temporarily disable versionlock to check for updates
echo "--- Updates blocked by version locks ---"
dnf check-update --disableplugin=versionlock 2>/dev/null | \
grep -f <(dnf versionlock list 2>/dev/null | awk -F: '{print $1}' | sed 's/-[0-9].*//')
echo ""
echo "--- Currently locked packages ---"
dnf versionlock list

EL 10 Notes: versionlock is the same as on EL 9

Section titled “EL 10 Notes: versionlock is the same as on EL 9”

EL 10 still uses DNF 4 (4.20), and versionlock is still provided by dnf-plugin-versionlock, with the same usage and config file as EL 9:

ItemEL 9EL 10
Installationsudo dnf install dnf-plugin-versionlockSame
Config file location/etc/dnf/plugins/versionlock.listSame
File formatOne NEVRA string per lineSame
versionlock basic usage
# Lock a package
dnf versionlock add nginx
# List locked packages
dnf versionlock list
# Remove a lock
dnf versionlock delete nginx
View the versionlock config file
cat /etc/dnf/plugins/versionlock.list

If some lock rules stop working after the upgrade (the old NEVRA does not exist on EL 10), re-lock by package name. The idea: before upgrading, record which packages are locked on EL 9; after upgrading, re-lock them by name on EL 10 with versionlock add. This locks to versions that actually exist in the EL 10 repositories and avoids copying stale NEVRAs that point to non-existent versions.

Because the versionlock list holds name-epoch:version-release.arch NEVRA globs, truncating the package name with sed/awk is unreliable (e.g. java-17-openjdk or gcc-toolset-13-gcc get cut incorrectly). The safest approach is to archive the raw list for manual review — you usually lock only a handful of packages whose names you know:

EL 9: archive the lock records before upgrading (as-is)
# Save verbatim for cross-checking after the upgrade
dnf versionlock list 2>/dev/null | tee /root/versionlock-el9.txt
EL 10: re-lock by package name after upgrading
# Cross-check against /root/versionlock-el9.txt and list the packages you actually
# want to lock here (example — replace with your real ones)
for pkg in kernel nginx java-17-openjdk; do
sudo dnf versionlock add "$pkg"
done
sudo dnf versionlock list

If you lock many packages and need to extract names in bulk, resolving against installed packages with rpm is more reliable than truncating with sed:

Optional: resolve package names reliably with rpm
# Strip the trailing .arch glob from each record, then let rpm resolve the canonical name
dnf versionlock list 2>/dev/null | sed 's/\.\*$//' | while read -r nevra; do
[ -n "$nevra" ] && rpm -q --qf '%{NAME}\n' "$nevra" 2>/dev/null
done | sort -u