You run apt install or apt update on an Ubuntu or Debian machine and it stops with a lock error. A typical run looks like this:
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 245 (apt-get)
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
It most often happens right after boot, or the first time you log in to a new server, because the machine is busy installing its own security updates. On a terminal, plain apt is a little friendlier and waits instead of failing, printing the same message with a “Waiting for cache lock” prefix. Older releases may leave out the holder’s PID, but the meaning is the same.
Applies to: Ubuntu, Debian and anything built on them. Run the commands with sudo. If your error says Permission denied and are you root? instead, that is a different problem: you forgot sudo.
What is going on
APT and dpkg are built to run one at a time. Two package tools changing the package database at once would corrupt it, so each takes a lock first. The lock is held by a running process, not by a file. The file under /var/lib/dpkg/ is only the thing the lock is placed on. Debian’s own dpkg FAQ says the same: the locks are region locks bound to a process, so when that process finishes or is killed the lock is released automatically, and the file is left behind on purpose.
That is why the first question is always who is holding it. Usual suspects:
- The automatic updater. On Ubuntu, systemd timers (
apt-daily.timerandapt-daily-upgrade.timer) run/usr/lib/apt/apt.systemd.daily, which refreshes package lists and runsunattended-upgrade. The timers have a random delay and can fire as soon as a machine that was off comes back up. - A desktop updater or software centre. GNOME Software, Discover and the “Software Updater” window run through PackageKit (
packagekitd). - Your own earlier command still running in another terminal, tmux or SSH session.
- A hung or crashed process, which is rare. Even then the lock goes away when the process does.
The error also tells you which phase you collided with. The lock for the package database changes is /var/lib/dpkg/lock-frontend (and /var/lib/dpkg/lock). Refreshing the package lists takes /var/lib/apt/lists/lock instead, so a second apt-get update during an update fails with that path. Same cause, same fix.
Diagnosis
1. Read the PID out of the error
Recent APT prints the holder for you: It is held by process 245 (apt-get). Use that number. Look at what it is and how long it has been running (etime):
ps -o pid,ppid,etime,stat,cmd -p 245
Or list everything that looks like a package manager:
ps -eo pid,ppid,etime,stat,cmd | grep -E "apt|dpkg|unattended|packagekit" | grep -v grep
Names to expect: apt.systemd.daily, unattended-upgr (the name is cut at 15 characters), packagekitd, aptd, or another apt/dpkg of your own. If the process name is something you do not recognise, stop and find out what it is before going any further.
2. Ask the system who has the lock open
This does not depend on the error message. Both tools list the processes that have the lock files open:
sudo fuser -v /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/lib/apt/lists/lock
sudo lsof /var/lib/dpkg/lock-frontend
Here is what that looked like while a real apt-get install held the lock (reproduced in an Ubuntu 24.04 container):
/var/lib/dpkg/lock-frontend:
root F.... apt-get
The kernel’s own list of held locks agrees (cat /proc/locks shows a POSIX ADVISORY WRITE line with the holder’s PID). If fuser prints nothing and exits with status 1, nobody holds the lock. Skip to the Root cause section: you do not have a lock problem.
Run these as root. Without sudo, fuser and lsof cannot see other users’ processes and can print nothing, which looks exactly like “nobody holds it”. On a normal system sudo is enough.
3. Is it making progress?
An updater that has been running for a few minutes is working. One that has been running for hours is suspicious. Check the logs and activity:
systemctl list-timers "apt-daily*"
sudo tail -n 20 /var/log/unattended-upgrades/unattended-upgrades.log
sudo tail -n 20 /var/log/dpkg.log
top -p 245
New lines in dpkg.log or non-zero CPU or disk use means it is installing. Leave it alone. No new log lines for a long time, 0% CPU and no disk activity means it may really be stuck.
Root cause
Another process holds the dpkg frontend lock, almost always the automatic updater doing its normal job. The lock was working as designed: it stopped you from starting a second package manager on top of the first. Nothing is broken, and no file needs removing.
A point worth getting right, because many guides get it wrong: after a crash or a hard reboot, nothing holds the lock any more. The lock lived in the kernel on behalf of a process, and the process is gone. If fuser shows no holder, the lock is free and the error will not come back. What can be left over after a crash is a half-finished package operation, which is a different problem fixed with dpkg --configure -a.
The fix
Do not delete /var/lib/dpkg/lock*, /var/cache/apt/archives/lock or /var/lib/apt/lists/lock. Tutorials that tell you to rm them treat the file as the lock. It is not. If an installer really is running, removing the file lets a second tool in on top of it, which can corrupt /var/lib/dpkg/status. dpkg itself prints this warning when it is refused: “removing the lock file is always wrong, can damage the locked area and the entire system.”
If the holder is working: wait
Most of the time this is the whole fix. Give an unattended upgrade a few minutes and rerun your command. To make the command wait for you instead of failing, give apt a lock timeout in seconds:
sudo apt-get -o DPkg::Lock::Timeout=300 install <package>
It retries every few seconds and prints Waiting for cache lock: ... It is held by process N until the lock is free or the timeout runs out. If you do this often on one machine, you can also move the update timers, see Notes.
If the holder is a leftover of yours
If it is your own earlier apt in another window, go back to that window. It may be sitting at a “Do you want to continue? [Y/n]” prompt.
If the holder is genuinely hung
Only after step 3 of the diagnosis showed no progress for a long time. Ask it to stop politely, give it a minute, and only then consider something stronger:
sudo kill -TERM 245
# wait a minute, check again
ps -p 245
# only if it is still there and still not doing anything:
sudo kill -KILL 245
Debian’s dpkg FAQ describes the same approach: kill the running process, never remove the lock file. Killing a process in the middle of unpacking packages can leave dpkg half-way through, so finish the job afterwards:
sudo dpkg --configure -a
sudo apt-get install -f
dpkg --configure -a finishes configuring every package that was unpacked but not set up. apt-get install -f repairs broken dependencies. Run them only after a process was interrupted. On a healthy system they print nothing and do nothing.
Verification
sudo fuser -v /var/lib/dpkg/lock-frontend ; echo "exit: $?" # exit 1 and no output = nobody holds it
sudo apt update
sudo dpkg --audit # prints nothing when the package database is consistent
apt update should finish without a lock error, and dpkg --audit should print nothing. The lock files will still exist (ls -l /var/lib/dpkg/lock-frontend). That is expected and correct.
This was tested by killing a running apt-get install with kill -9 in a container and then running apt-get install again: the lock was free immediately, fuser exited with status 1, and nothing had to be deleted.
Notes
- Fresh VM or first login. If a new server throws this on first use, it is nearly always the first unattended-upgrade run. Waiting a few minutes is usually enough, longer on a slow disk or with a big backlog of updates.
- Do not trust “is the service active”. The unit that does the work is
apt-daily-upgrade.service(andapt-daily.servicefor list refreshes), started by the timers, and the process isunattended-upgrade. Look for the running process, as in step 1, not for the state of a unit calledunattended-upgrades.service. - Hitting this in scripts or cloud-init? Use
-o DPkg::Lock::Timeout=NNNon every apt call instead of sleeping in a loop or removing locks. - Changing when updates run. To move the schedule, override the timers with
sudo systemctl edit apt-daily.timerandsudo systemctl edit apt-daily-upgrade.timer(the Ubuntu server guide and the Debian wiki both describe this). Do not disable security updates just to avoid a lock message. - Permission denied is not a lock problem.
Could not open lock file ... Permission deniedandare you root?means run it withsudo.
Still locked and fuser finds nothing? Post the full error, the output of ps and sudo dpkg --audit in The Patch Panel and we will work through it. The best answer earns points on Top of the Stack.