Imagine you start a routine apt upgrade or dnf upgrade on a server over SSH, your Wi-Fi drops for ten seconds, and when you reconnect, the upgrade is no longer running.
That alone is annoying, but the bigger problem shows up when you try to run the upgrade again, because on Ubuntu and Debian you are likely to see errors like these:
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 2143 (unattended-upgr) E: dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.
On RHEL-based distributions, the problem looks different, because dnf may stop and wait for another process to finish, or dnf check may start reporting that the same package is installed twice.
Most people’s first reaction is to delete the lock files and force the install, but that often turns a small problem into a much bigger one.
The good news is that both package managers keep detailed records of what they were doing, so they can almost always repair themselves without you reinstalling the server.
You just need to run the right commands in the right order, and this guide walks you through them for both distribution families.
Why apt and dnf Lock the Package Database
Before running any repair commands, it helps to understand what the package manager was doing when the upgrade stopped, because each repair step undoes one specific part of that unfinished work.
On Debian-based systems, apt relies on dpkg, the lower-level tool that actually installs packages. Before changing anything, dpkg locks two files, /var/lib/dpkg/lock-frontend and /var/lib/dpkg/lock, so that two programs can’t write to the package database at the same time.
This is a file lock managed by the kernel, which means Linux releases it automatically as soon as the process holding it exits or is killed. So if you still see a lock error after reconnecting, it almost always means another process is still running, and in most cases it’s the background unattended-upgrades service.
dpkg also records a state for every package, such as “unpacked” or “half-configured“. When an upgrade stops partway through, some packages are left in these in-between states, because their files were copied to the disk but their setup scripts never ran. That is exactly what the “dpkg was interrupted” message is telling you.
On RHEL-based systems, RPM (the RPM Package Manager, which dnf uses underneath) upgrades a package by installing the new version first and then removing the old one. If the upgrade stops between those two steps, both versions are recorded as installed, and dnf won’t touch those packages until the duplicate is cleaned up.
Check Which Process Holds the Lock with fuser and ps
Since a running process is the most common reason for a lock error, that is the first thing to rule out. You’ll need sudo access on the affected server, and if you’re connected over SSH, start a tmux session before going any further (install it with apt or dnf if it isn’t already there), because losing your connection a second time in the middle of a repair would only make things worse.
On Ubuntu and Debian, the fuser command shows which process is holding the dpkg lock file:
sudo fuser -v /var/lib/dpkg/lock-frontend
Output:
USER PID ACCESS COMMAND
/var/lib/dpkg/lock-frontend:
root 2143 F.... unattended-upgr
If the process is unattended-upgrades, the safest choice is to wait for it to finish, because stopping it in the middle of an install can leave the system in the same broken state you’re trying to fix. Only if the process has clearly been stuck for a long time should you stop it with sudo kill 2143, using the PID from your own output.
If fuser shows no process at all but the lock error keeps appearing, the lock files are left over from the interrupted upgrade, and only in that case should you remove them:
sudo rm /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock
On Rocky Linux, RHEL, and AlmaLinux, dnf doesn’t fail with a lock error. Instead, it pauses and prints a message such as Waiting for process with pid 3871 to finish.
You can find out what that process is with ps, replacing the PID with the one from your message:
ps -fp 3871
If it turns out to be a background dnf-makecache or dnf-automatic job, give it a few minutes to finish. If the PID no longer exists, your next dnf command will run normally.
Repair a Crashed apt Upgrade with dpkg
Now that nothing is holding the lock, the next step on Ubuntu and Debian is to finish setting up the packages that were left half-done. This is the command the “dpkg was interrupted” error asks you to run:
sudo dpkg --configure -a
You’ll see a series of “Setting up” lines as dpkg works through the list. If the command prints nothing, that’s fine too, because it simply means no packages were waiting to be configured.
Finishing those packages often reveals missing dependencies, which apt reports with an error like E: Unmet dependencies. Try ‘apt –fix-broken install’ with no packages (or specify a solution).
You can repair them with the following command:
sudo apt install -f
Once apt has finished, check that the package database is consistent again, and then complete the upgrade you originally started:
sudo dpkg --audit sudo apt update sudo apt upgrade
Repair a Crashed dnf Upgrade with dnf
The apt repair was about finishing work that dpkg left half-done, but on RHEL-based systems, the usual leftover is duplicate packages, so the first step is to find them:
sudo dnf check
Output:
openssl-libs-1:3.2.2-6.el10.x86_64 is a duplicate with openssl-libs-1:3.2.2-4.el10.x86_64
Each line shows a package that is recorded in two versions, which is the “new version installed, old version not yet removed” state described earlier. The exact version numbers will be different on your system.
You can remove the older copies with this command:
sudo dnf remove --duplicates
If dnf or rpm complains about the package database itself instead, with errors such as error: cannot open Packages database in /var/lib/rpm, rebuild the RPM database indexes:
sudo rpm --rebuilddb
With the duplicates removed and the database readable again, the last step brings every package back in line with your repositories:
sudo dnf clean all sudo dnf distro-sync
Prevent Broken Upgrades with tmux and dnf history
Now that your system is healthy again, a few habits will help you avoid going through this repair a second time. Most interrupted upgrades are caused by dropped SSH connections, so run large upgrades inside tmux, which keeps the upgrade running on the server even if your connection drops and lets you reconnect to it later with tmux attach.
On production servers, take a snapshot or confirm that your backups are current before any major upgrade, because a snapshot turns a broken upgrade into a quick rollback instead of a long repair.
On RHEL-based systems, dnf also keeps a record of every transaction, which you can list with dnf history. If one particular upgrade caused problems, sudo dnf history undo ID can roll it back, as long as the older package versions are still available in your repositories.
Summary
A failed upgrade can look alarming, but both apt and dnf keep enough information to recover cleanly. Start by finding out what’s holding the lock, and then let dpkg --configure -a, apt install -f, dnf check, and dnf distro-sync finish the repair instead of forcing it.
apt, dpkg, and day-to-day system administration.We’d love to hear how you handle this on your own servers. Do you let unattended-upgrades run on production, or do you turn it off and patch by hand? And if you’ve hit a dpkg or rpm error that none of these steps fixed, paste the exact message in the comments so we can work through it together.






