Updating Linux Safely

Updating Linux Safely

Linux updates are generally safe and easy. Run a command, wait, done. But “generally” is doing real work in that sentence. Kernel updates can break proprietary drivers. Library updates can reveal incompatibilities. A config file update can change a service’s behaviour. Major version upgrades are a category of their own.

This guide covers how to update correctly on the main distribution families, what to do before major changes, how to investigate what a pending update changes, and how to recover when something does go wrong.

The basics: running updates correctly

Debian and Ubuntu

# The two-step: refresh index, then upgrade
sudo apt update && sudo apt upgrade

# For major changes (dependency resolution, package set changes)
sudo apt full-upgrade

# See what is pending before installing
apt list --upgradable

# See what full-upgrade would change without committing
sudo apt full-upgrade --dry-run

# Apply only security updates
sudo apt upgrade --with-new-pkgs $(apt-get -s dist-upgrade | grep "^Inst" | grep -i security | awk '{print $2}')

For servers on Ubuntu LTS or Debian stable, apt upgrade is the safe daily command. apt full-upgrade is needed for kernel updates and anything that requires changing the installed package set.

Fedora and RHEL

# Refresh metadata and upgrade everything
sudo dnf upgrade --refresh

# Preview changes without installing
sudo dnf upgrade --dry-run

# Apply only security updates
sudo dnf upgrade --security

# Apply security updates for a specific CVE
sudo dnf upgrade --cve CVE-2024-12345

Arch Linux

# Full system upgrade (the only supported update command)
sudo pacman -Syu

# Check for updates without installing
pacman -Qu

# Review the Arch news before upgrading (important on rolling release)
# https://archlinux.org/news/

On Arch, always read the news at archlinux.org before upgrading. Manual intervention steps are published there when an update requires action beyond the standard pacman -Syu.

openSUSE

# Leap (stable)
sudo zypper refresh && sudo zypper update

# Tumbleweed (rolling)
sudo zypper refresh && sudo zypper dup

# Preview changes
sudo zypper dup --dry-run

Reviewing what an update changes

Before applying updates on a production system, it is worth understanding what is changing:

# Debian/Ubuntu: see changelogs before installing
apt changelog nginx
apt changelog linux-image-generic

# Fedora: see advisory details
dnf updateinfo list
dnf updateinfo info CVE-2024-12345

# Arch: check the update log
pacman -Syu 2>&1 | tee /tmp/upgrade-$(date +%Y%m%d).log

# See which services would be affected
# (packages that own running services)
apt list --upgradable 2>/dev/null | awk -F'/' '{print $1}' | xargs -I{} systemctl is-active {} 2>/dev/null | grep active

For kernel updates specifically, check whether your proprietary drivers or out-of-tree modules will be rebuilt:

# See the current kernel version
uname -r

# See available kernel updates on Debian/Ubuntu
apt list --upgradable 2>/dev/null | grep linux-image

# Check if DKMS modules will be rebuilt for the new kernel
dkms status

Snapshots before major updates

A snapshot lets you roll back to a known-good state if an update breaks something. The method depends on your filesystem.

Btrfs with Snapper

Btrfs is the default filesystem on openSUSE and is an option on Fedora and Ubuntu. Snapper creates and manages Btrfs snapshots:

# Install snapper
sudo apt install snapper            # Debian/Ubuntu
sudo dnf install snapper            # Fedora
# openSUSE has Snapper pre-installed

# Create a snapshot before upgrading
sudo snapper create --description "before-upgrade-$(date +%Y%m%d)"

# List snapshots
sudo snapper list

# Take a snapshot, run upgrades, then snapshot again (Snapper's built-in workflow)
sudo snapper create --type pre --description "pre-upgrade"
sudo apt full-upgrade
sudo snapper create --type post --description "post-upgrade"

# Roll back to a snapshot
sudo snapper rollback <snapshot-number>
sudo reboot

Snapper integrates with the package managers on openSUSE to automatically create pre/post snapshots around every zypper operation.

Timeshift

Timeshift works on any filesystem using rsync, and on Btrfs using native snapshots:

# Install Timeshift
sudo apt install timeshift            # Debian/Ubuntu
sudo dnf install timeshift            # Fedora

# Create a snapshot from the command line
sudo timeshift --create --comments "before major update" --tags D

# List snapshots
sudo timeshift --list

# Restore a snapshot
sudo timeshift --restore --snapshot "2026-06-28_10-00-00"

# Delete a specific snapshot
sudo timeshift --delete --snapshot "2026-06-28_10-00-00"

Timeshift does not back up personal data in /home. It is a system snapshot tool for /etc, /usr, /var, and related system directories. Use a separate backup solution (rsync, Borg, restic) for your data.

LVM snapshots

On systems using LVM:

# Create an LVM snapshot of the root volume
sudo lvcreate -L 10G -s -n root-snap /dev/vg0/root

# If something breaks, mount the snapshot to recover files
sudo mkdir /mnt/snap
sudo mount /dev/vg0/root-snap /mnt/snap

# Or merge the snapshot back (rolls back root)
sudo lvconvert --merge /dev/vg0/root-snap
sudo reboot

# Remove a snapshot you no longer need
sudo lvremove /dev/vg0/root-snap

Holding back specific packages

When a specific package update is known to cause problems, hold it while letting everything else update.

Debian/Ubuntu

# Hold a package
sudo apt-mark hold nginx
sudo apt-mark hold linux-image-generic

# Release a hold
sudo apt-mark unhold nginx

# List held packages
apt-mark showhold

# Upgrade everything except held packages
sudo apt upgrade                    # held packages are automatically skipped

# Alternative: exclude in apt.conf
echo 'APT::Get::HoldBroken "true";' | sudo tee /etc/apt/apt.conf.d/99noupgrade-nginx
# Or add to /etc/apt/preferences:
# Package: nginx
# Pin: release *
# Pin-Priority: -1

Fedora/RHEL

# Hold a package with versionlock
sudo dnf versionlock add nginx

# Release the hold
sudo dnf versionlock delete nginx

# See all locked packages
dnf versionlock list

Arch

# Exclude a package from upgrades in /etc/pacman.conf
# Find or add the IgnorePkg line:
# IgnorePkg = nginx someother-package

# Or exclude an entire group
# IgnoreGroup = kde

# Upgrade while temporarily ignoring a held package
sudo pacman -Syu --ignore nginx

Kernel updates

Kernel updates deserve special attention because they require a reboot and can affect hardware compatibility.

# See currently running kernel
uname -r

# See all installed kernels (Debian/Ubuntu)
dpkg -l | grep linux-image

# See all installed kernels (Fedora)
dnf list installed kernel

# Arch (all kernels are installed to /boot)
ls /boot/vmlinuz*

# After a kernel update, reboot to load it
sudo reboot

# Verify you are running the new kernel after reboot
uname -r

# On Debian/Ubuntu: remove old kernels while keeping current and one previous
sudo apt autoremove

# On Fedora: remove old kernels manually
sudo dnf remove --oldinstallonly --setopt=installonly_limit=3 kernel

If the new kernel causes problems, older kernels remain installed and are selectable in the GRUB menu at boot. Hold the spacebar or Shift at boot to access the GRUB menu, then navigate to “Advanced options” to choose an older kernel.

GRUB and kernel selection

# List available kernels in GRUB
grep -E "^menuentry|submenu" /boot/grub/grub.cfg | head -20

# Set a specific kernel as the default (temporarily)
# The GRUB submenu numbering: 0 is the first menu entry
# "1>2" means submenu 1, entry 2
sudo grub-set-default "1>2"

# Update GRUB config after changing /etc/default/grub
sudo update-grub                    # Debian/Ubuntu
sudo grub2-mkconfig -o /boot/grub2/grub.cfg  # Fedora/RHEL

# To boot the previous kernel once without changing the default
# Hold Shift at boot, select "Advanced options", then the older kernel

Recovering from a broken upgrade

When an upgrade fails partway through:

Debian/Ubuntu

# Fix packages stuck in a broken state
sudo dpkg --configure -a

# Fix missing dependencies
sudo apt install -f

# Retry the upgrade
sudo apt upgrade

# If the package manager database is corrupted
sudo apt clean
sudo apt update
sudo apt upgrade

# Nuclear option: reinstall the package that is causing problems
sudo apt install --reinstall package-name

DNF (Fedora/RHEL)

# Roll back the failed transaction
dnf history list
sudo dnf history undo <ID>

# If that is not available, reinstall the affected packages
sudo dnf reinstall package-name

# Clean the cache and retry
sudo dnf clean all
sudo dnf upgrade --refresh

Pacman (Arch)

# If pacman is interrupted mid-upgrade
# Remove the lock file first
sudo rm /var/lib/pacman/db.lck

# Retry the upgrade
sudo pacman -Syu

# If packages are in a half-installed state
# Force reinstall of the affected package from cache
sudo pacman -U /var/cache/pacman/pkg/package-*.pkg.tar.zst

# If the cache does not have it, force download and reinstall
sudo pacman -S --overwrite '*' package-name

Automatic security updates

For servers where patching promptly matters but manual intervention is impractical:

Debian/Ubuntu: unattended-upgrades

# Install (usually already present on Ubuntu)
sudo apt install unattended-upgrades

# Enable it
sudo dpkg-reconfigure unattended-upgrades

# Configuration file
sudo nano /etc/apt/apt.conf.d/50unattended-upgrades

# Key options:
# Unattended-Upgrade::Allowed-Origins -- which repos to pull from
# Unattended-Upgrade::Remove-Unused-Dependencies "true"
# Unattended-Upgrade::Automatic-Reboot "false"      # set true for servers
# Unattended-Upgrade::Automatic-Reboot-Time "02:00" # reboot time if enabled

# Simulate what would be installed
sudo unattended-upgrade --dry-run --debug

# View the log
sudo cat /var/log/unattended-upgrades/unattended-upgrades.log

Fedora/RHEL: dnf-automatic

# Install
sudo dnf install dnf-automatic

# Configure
sudo nano /etc/dnf/automatic.conf
# Set: upgrade_type = security
# Set: apply_updates = yes

# Enable the timer
sudo systemctl enable --now dnf-automatic.timer

# Check status
systemctl status dnf-automatic.timer

Quick update safety checklist

For routine updates on a desktop or server:

  1. Check for any manual intervention notices (Arch: archlinux.org/news, RHEL: access.redhat.com/errata)
  2. Create a snapshot if the system is critical or if a major package is updating
  3. Run the update command with --dry-run first on servers
  4. Apply the update
  5. Check that key services are still running (systemctl --failed)
  6. Reboot if the kernel was updated
# Post-update health check
systemctl --failed                  # see failed services
journalctl -p 3 -xb                 # errors since last boot
df -h                               # check disk space
uname -r                            # confirm running kernel version

Updating Linux regularly is one of the most effective things you can do for system security. The goal is not to avoid updates — it is to have enough observability and recovery options that updates are a routine, low-stress operation.

Frequently Asked Questions

How often should I update Linux?

For desktop systems, running updates weekly is a reasonable baseline. Security updates should be applied promptly — within a day or two of release for critical vulnerabilities. For servers, the same logic applies, but you should test significant updates in a staging environment first and schedule maintenance windows for changes that require a reboot. On rolling-release distributions like Arch or Tumbleweed, more frequent updates (every few days) reduce the risk of a large batch of changes landing at once.

Will updating Linux break my system?

Routine updates on stable distributions like Ubuntu LTS, Debian, or Fedora rarely break things. Package maintainers test updates before releasing them and security patches are conservative by nature. The higher-risk situations are major version upgrades (e.g., Ubuntu 22.04 to 24.04), kernel updates on systems with out-of-tree drivers, and updates to core system libraries like glibc or systemd. Snapshots before major changes give you a safe recovery path.

What is the difference between a security update and a regular update?

A security update patches a known vulnerability, usually with minimal code changes and no new features. It is low-risk and should be applied promptly. A regular feature update brings bug fixes and new functionality and may involve larger code changes. Most package managers distinguish between these: apt-get upgrade applies only security-compatible updates while apt-get dist-upgrade handles more significant changes. On Debian and Ubuntu, unattended-upgrades is configured by default to apply security updates automatically.

How do I roll back an update in Linux?

The method depends on your setup. On Btrfs filesystems with Snapper or Timeshift, you can roll back to a pre-update snapshot in minutes. On DNF (Fedora/RHEL), dnf history undo rolls back a specific transaction. On apt systems, you can downgrade individual packages with apt install package=older-version if the old version is still in the cache or a pinned repository. For kernel updates specifically, older kernels remain installed and selectable in the GRUB bootloader menu.

Should I update the kernel?

Yes, generally. Kernel updates include security fixes, hardware support improvements, and performance enhancements. On distributions like Ubuntu, the kernel is updated as part of regular apt upgrade. You should apply kernel updates, but reboot after applying them — a running system stays on the old kernel until reboot. On systems with third-party kernel modules (like NVIDIA proprietary drivers or VirtualBox), kernel updates can break those modules until DKMS rebuilds them, which happens automatically if DKMS is configured correctly.