Solucionar el error de apt "Could not get lock"
Por qué apt se queda de repente bloqueado, qué proceso hay detrás y cómo encontrarlo con lsof y fuser. También verás cómo eliminar el archivo de bloqueo sin dañar la base de datos de paquetes.
Quieres instalar rápidamente un paquete y apt se interrumpe al cabo de un segundo. En lugar de la lista de paquetes aparece una línea que se busca millones de veces en todo el mundo: Could not get lock. El reflejo de muchas guías es borrar de inmediato el archivo de bloqueo. Justo ese reflejo convierte con frecuencia una espera inofensiva en una base de datos de paquetes dañada. Este artículo repasa el orden que funciona en un sistema en producción: primero averiguar quién bloquea, después esperar y solo al final intervenir.
Todos los comandos se ejecutan como root. Si trabajas como usuario normal, antepón sudo. Y una aclaración previa: el tema afecta únicamente a Debian y Ubuntu. En AlmaLinux, Rocky Linux, RHEL y Oracle Linux no existen ni apt-get ni /var/lib/dpkg, dnf resuelve la cuestión de otra manera, consulta el apartado sobre las diferencias entre sistemas más abajo.
El mensaje de error, palabra por palabra
Según la versión y según lo que apt estuviera intentando hacer, la salida cambia. Estas son las variantes con las que te vas a encontrar:
E: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 1234 (unattended-upgr)
N: Be aware that removing the lock file is not a solution and may break your system.
E: Unable to acquire the dpkg frontend lock (/var/lib/dpkg/lock-frontend), is another process using it?
E: Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)
E: Unable to lock the administration directory (/var/lib/dpkg/), is another process using it?
E: Could not get lock /var/lib/apt/lists/lock. It is held by process 987 (apt-get)
E: Unable to lock directory /var/lib/apt/lists/
dpkg: error: dpkg frontend lock is locked by another process
dpkg: error: dpkg status database is locked by another process
La localización al español muestra lo mismo como "No se pudo obtener el bloqueo" o "No se pudo bloquear el directorio de administración". Lo importante es la indicación entre paréntesis: el nombre del proceso. unattended-upgr, apt-get, aptitude, packagekitd o dpkg ya te dicen dónde tienes que buscar.
Cuatro archivos de bloqueo, cuatro mensajes distintos
apt y dpkg no bloquean en un solo punto, sino en cuatro. El archivo que aparece en el mensaje revela en qué fase se ha producido el conflicto:
- /var/lib/apt/lists/lock protege las listas de paquetes descargadas. Este mensaje aparece con
apt update. - /var/cache/apt/archives/lock protege el directorio de descarga de los archivos .deb. Este mensaje aparece mientras apt descarga paquetes.
- /var/lib/dpkg/lock-frontend es el bloqueo de nivel superior. Garantiza que solo un frontend (apt, apt-get, aptitude, Ansible, un script de instalación) hable con dpkg a la vez. Este es el mensaje que verás con más frecuencia.
- /var/lib/dpkg/lock protege la base de datos de estado propiamente dicha. Quien mantiene este bloqueo está escribiendo realmente en
/var/lib/dpkg/status.
Los cuatro archivos están vacíos. No contienen datos, ni un PID, nada. El bloqueo no está en el contenido, sino en un flock sobre el descriptor de archivo abierto. Este es el punto decisivo que la mayoría de las guías se saltan.
Por qué borrar a ciegas puede dañar la base de datos de paquetes
Como el bloqueo depende del descriptor de archivo y no del nombre del archivo, al borrarlo ocurre lo siguiente: el proceso en marcha conserva su descriptor y sigue trabajando sin inmutarse. El archivo ha desaparecido del directorio, pero para él sigue existiendo. Tu segunda llamada a apt crea un archivo nuevo con el mismo nombre, lo bloquea con éxito y cree que tiene vía libre.
A partir de ese momento, dos procesos escriben a la vez en /var/lib/dpkg/status, descomprimen archivos en paralelo en el mismo directorio de destino y se ejecutan mutuamente los triggers. El resultado va desde paquetes a medio configurar hasta una base de datos de estado que dpkg ya no puede leer. De eso mismo avisa el propio apt con la línea N: Be aware that removing the lock file is not a solution and may break your system.
Eliminar el archivo de bloqueo solo es admisible cuando se ha demostrado que ya no queda ningún proceso que lo mantenga. Esa demostración es el núcleo de esta guía, no el rm.
El caso más frecuente: la actualización automática está en marcha
En unos nueve de cada diez casos en un servidor recién instalado, el culpable es inofensivo y legítimo: unattended-upgrades. Ubuntu activa por defecto las actualizaciones de seguridad desatendidas en sus imágenes de servidor y de cloud, y dos timers de systemd ponen en marcha el proceso:
- apt-daily.timer se ejecuta a las 06:00 y a las 18:00 con un retardo aleatorio de hasta doce horas y actualiza las listas de paquetes.
- apt-daily-upgrade.timer se ejecuta a las 06:00 con un retardo aleatorio de hasta 60 minutos e instala las actualizaciones de seguridad.
El retardo aleatorio explica por qué el error aparece a horas aparentemente arbitrarias. En las imágenes cloud se suma el primer arranque: cloud-init ejecuta por su cuenta un apt update en el primer boot. Quien inicia sesión dos minutos después del aprovisionamiento y quiere instalar algo de inmediato se topa casi con seguridad con el bloqueo. Por eso, si estás configurando un servidor nuevo, merece la pena seguir el orden de nuestra lista de comprobación para servidores root nuevos: primero respirar, después instalar.
El estado de la actualización automática se consulta así:
systemctl list-timers 'apt-daily*'
systemctl status unattended-upgrades.service
journalctl -u apt-daily-upgrade.service --since "-2h" --no-pager
tail -n 30 /var/log/unattended-upgrades/unattended-upgrades.log
¿Quién mantiene el bloqueo? Diagnóstico con lsof y fuser
Antes de cualquier intervención está la pregunta de si todavía hay alguien trabajando. Dos herramientas lo responden de forma fiable. Si no están, vienen en los paquetes lsof y psmisc, que evidentemente solo podrás instalar cuando el bloqueo haya desaparecido. Por eso, en sistemas en producción ambas forman parte del equipamiento básico.
lsof /var/lib/dpkg/lock-frontend
lsof /var/lib/dpkg/lock
lsof /var/cache/apt/archives/lock
lsof /var/lib/apt/lists/lock
Una salida típica tiene este aspecto:
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
unattended 1234 root 5uW REG 254,1 0 1049 /var/lib/dpkg/lock-frontend
La W detrás del número de descriptor de archivo significa: bloqueo de escritura activo. Solo esa entrada bloquea realmente a apt, un descriptor simplemente abierto sin W no lo hace. Así que aquí está todo en orden, el proceso está trabajando.
Si en cambio no vuelve ninguna salida, ya no hay nadie que mantenga el bloqueo. Cuenta con que lsof devuelva en este caso normal el código de retorno 1, sin ningún mensaje de error. Lo mismo vale para fuser. En un script con set -e o en un encadenamiento con &&, el diagnóstico se interrumpe precisamente cuando el resultado es bueno. Escribe ahí lsof /var/lib/dpkg/lock-frontend || true.
Una advertencia importante sobre el valor probatorio: una salida vacía significa realmente "nadie bloquea" solo si el archivo de bloqueo no se ha borrado antes. Si se eliminó mientras un proceso todavía lo mantenía, ese proceso sigue reteniendo el inodo huérfano, pero bajo el nombre del archivo lsof ya no ve nada. Por eso comprueba siempre además la lista de procesos.
Sin lsof, fuser hace lo mismo:
fuser -v /var/lib/dpkg/lock-frontend
Y un vistazo a la lista de procesos muestra además cuánto tiempo lleva ya en marcha la operación. La columna etimes indica el tiempo de ejecución en segundos, lo que ayuda a valorar la situación:
ps -eo pid,ppid,etimes,stat,cmd | grep -E 'apt|dpkg|unattended' | grep -v grep
Interpreta el resultado así:
- Tiempo de ejecución por debajo de diez minutos, estado
SoR: funcionamiento normal. Espera. - Tiempo de ejecución superior a una hora, acceso a la red, servidores espejo lentos: sigue siendo plausible. Comprueba con
tail -f /var/log/apt/term.logsi algo se mueve. - Estado
D(uninterruptible sleep) durante mucho tiempo: el proceso está colgado en la ruta de entrada y salida. La causa suele ser un disco lleno o defectuoso, no apt en sí. - Estado
T(detenido): alguien ha parado la operación con Ctrl+Z. Déjala continuar conkill -CONT PID. - El proceso ya no existe y el bloqueo permanece: ahora, y solo ahora, está justificado eliminar el archivo de bloqueo.
Una causa frecuente e infravalorada es una partición llena: dpkg se interrumpe en mitad de la descompresión y deja exactamente ese estado. Si df -h /var se acerca al 100%, lee primero cómo liberar espacio en un disco lleno bajo Linux y repara la gestión de paquetes solo después.
Esperar bien en lugar de abortar: DPkg::Lock::Timeout
Desde apt 2.x existe una opción que evita buena parte de los quebraderos de cabeza en los scripts. En lugar de abortar de inmediato, apt espera un número determinado de segundos a que se libere el bloqueo:
apt-get -o DPkg::Lock::Timeout=60 install -y htop
El valor -1 significa espera ilimitada. Para dejarlo fijo, colócalo en un archivo de configuración propio. La extensión que falta no es un descuido, apt lee el archivo también sin .conf:
echo 'DPkg::Lock::Timeout "300";' > /etc/apt/apt.conf.d/99lock-timeout
apt-config dump DPkg::Lock::Timeout
La segunda línea es la comprobación. Debe devolver DPkg::Lock::Timeout "300";, entonces el archivo está realmente activo.
Y ahora la limitación que casi ninguna guía menciona y que marca la diferencia cuando la cosa se pone seria: la opción no cubre los cuatro bloqueos. Comprobado en Debian 11, 12 y 13 y en Ubuntu 22.04 y 24.04, en cada caso con un proceso externo que mantiene el bloqueo mediante fcntl:
| Bloqueo | ¿apt espera con DPkg::Lock::Timeout? |
|---|---|
| /var/lib/dpkg/lock-frontend | sí, exactamente el tiempo configurado |
| /var/lib/dpkg/lock | sí |
| /var/cache/apt/archives/lock | no, aborta en menos de un segundo |
| /var/lib/apt/lists/lock | no, aborta en menos de un segundo |
En la práctica esto significa dos cosas. Primera: con apt-get update la opción no sirve de nada, porque ahí entra en juego el bloqueo de las listas. Incluso con DPkg::Lock::Timeout=-1, la llamada aborta al instante con E: Could not get lock /var/lib/apt/lists/lock y código de retorno 100 en lugar de esperar. Segunda: incluso con install, el timeout ayuda solo mientras el bloqueador mantenga el bloqueo del frontend. Si un proceso paralelo está en plena descarga y con ello mantiene el bloqueo del directorio de descargas, apt tampoco espera ni un segundo.
Por eso, en los roles de Ansible, los scripts de cloud-init y las pipelines de despliegue hace falta además un bucle de reintentos externo, o bien se serializa toda la acción mediante flock:
for i in $(seq 30); do apt-get update && break; sleep 10; done
flock /var/lib/apt/lists/lock apt-get update
En Debian 12, Debian 13, Ubuntu 22.04 y Ubuntu 24.04 la opción está disponible. En sistemas muy antiguos (Debian 9, Ubuntu 16.04) apt no la conoce y la ignora en silencio, sin devolver ningún error.
Cuando de verdad no queda ningún proceso: eliminar el archivo de bloqueo
Has demostrado con lsof y ps que ya nadie trabaja sobre la gestión de paquetes. Solo ahora toca intervenir. Si aun así sigue habiendo un proceso que tengas que terminar, usa primero la señal amable y nunca directamente kill -9:
kill -TERM 1234
Un SIGTERM le da a unattended-upgrades la posibilidad de cerrar limpiamente la llamada a dpkg en curso. Un SIGKILL en mitad de la descompresión, en cambio, deja justo esos paquetes a medio instalar que después tendrás que limpiar con esfuerzo. Tras el SIGTERM, espera al menos 30 segundos y vuelve a comprobarlo.
Si la lista de procesos está limpia, elimina los archivos de bloqueo:
rm -f /var/lib/dpkg/lock-frontend /var/lib/dpkg/lock /var/cache/apt/archives/lock /var/lib/apt/lists/lock
Los archivos se vuelven a crear automáticamente en la siguiente llamada a apt. No tienes que generarlos a mano ni asignarles permisos concretos. Pero eso significa también lo contrario: borrarlos no arregla permisos ni propietarios equivocados, solo elimina el nombre. Quien espere de ahí una reparación busca en el sitio equivocado. Y aún más cuidadoso que el rm es limitarse a vaciar los archivos, por ejemplo con : > /var/lib/dpkg/lock-frontend: así el inodo se conserva y un proceso antiguo que siga en marcha continúa siendo visible en lsof.
Después de la intervención: dpkg --configure -a
Este paso no es opcional. Una operación interrumpida deja paquetes en el estado "descomprimido, pero no configurado". apt se niega entonces con:
E: dpkg was interrupted, you must manually run 'dpkg --configure -a' to correct the problem.
El comando completa todos los pasos de configuración pendientes:
dpkg --configure -a
A continuación viene la comprobación de dependencias rotas:
apt-get --fix-broken install -y
apt-get check
Un detalle interesante para la revisión posterior: en /var/lib/dpkg/updates/ está el journal de dpkg. Si el directorio queda vacío después de dpkg --configure -a, todo se ha procesado. Si todavía hay ahí archivos numerados, la operación no ha llegado al final.
Cuando aun así ha salido mal: errores derivados y vuelta atrás
Aquí es donde otras guías terminan. Estos mensajes aparecen cuando se ha borrado demasiado pronto o se ha matado el proceso con demasiada dureza:
dpkg: error processing package nginx (--configure):
package is in a very bad inconsistent state; you should
reinstall it before attempting configuration
Errors were encountered while processing:
nginx
E: Sub-process /usr/bin/dpkg returned an error code (1)
La salida pasa por eliminar de forma forzada el paquete roto y volver a instalarlo. Usa --force-remove-reinstreq exclusivamente para ese único paquete afectado, nunca de forma general:
dpkg --remove --force-remove-reinstreq nginx
apt-get install -y nginx
Una segunda variante afecta a las listas de archivos:
dpkg: warning: files list file for package 'libssl3' missing; assuming package has no files currently installed
Eso lo arregla una reinstalación del mismo paquete con apt-get install --reinstall. Qué paquetes se encuentran realmente en un estado inconsistente lo muestra:
dpkg --audit
En el peor de los casos, el propio /var/lib/dpkg/status está dañado, algo reconocible por mensajes como dpkg: unrecoverable fatal error, aborting: parsing file '/var/lib/dpkg/status'. Entonces ayudan dos copias de seguridad que el sistema crea de forma automática: /var/lib/dpkg/status-old y las copias rotadas a diario en /var/backups/dpkg.status.0 hasta dpkg.status.6.gz. Restaura la más reciente de las dos antes de plantearte reinstalar el sistema. Y antes de nada, haz sin falta un backup del archivo dañado.
Diferencias entre los sistemas
Aquí no existe "una solución para todos", el punto de partida cambia bastante según el sistema:
- Ubuntu 22.04 y 24.04: unattended-upgrades está activo en las imágenes de servidor, el error forma parte del día a día. A eso se suma
needrestart, que abre un diálogo interactivo después de cada instalación y mantiene la operación abierta, con su bloqueo incluido, hasta que alguien confirma. Por eso, en los scripts conviene definirDEBIAN_FRONTEND=noninteractive. - Debian 12 y Debian 13: los timers
apt-daily.timeryapt-daily-upgrade.timertambién existen, y que realmente se actualice de forma automática depende de la imagen y de/etc/apt/apt.conf.d/20auto-upgrades. Comprobar en lugar de suponer. - Contenedores: en una imagen de Docker no se ejecuta systemd ni unattended-upgrades. Un bloqueo ahí significa casi siempre pasos paralelos en el build o una capa cacheada con un archivo de bloqueo que se quedó dentro. Quien construye imágenes con regularidad encontrará la introducción en nuestro artículo sobre Docker en Debian y Ubuntu.
- Sistemas de escritorio: allí el bloqueo suele estar en manos de
packagekitdo del gestor gráfico de actualizaciones, no de apt. - AlmaLinux, Rocky Linux y RHEL: ahí el problema no existe en esta forma, dnf usa
/var/run/dnf.pidy espera por defecto en lugar de abortar. El mensaje es entoncesWaiting for process with pid ... to finish. En qué se diferencia esta familia por lo demás lo muestra el artículo sobre htop en AlmaLinux, Rocky y RHEL.
Cómo saber que todo vuelve a estar limpio
Cuatro comprobaciones que, juntas, son concluyentes:
dpkg --audit
apt-get check
apt-get --fix-broken install -y
apt-get update
dpkg --audit en el caso ideal no muestra nada. apt-get check termina con las líneas de lectura de las listas de paquetes y sin errores. apt-get --fix-broken install informa 0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded. Y apt-get update se ejecuta sin ningún mensaje de bloqueo. Además, ls /var/lib/dpkg/updates/ debería mostrar un directorio vacío, y un vistazo a /var/log/dpkg.log debería mostrar las últimas acciones terminando con el estado status installed en lugar de half-configured:
tail -n 20 /var/log/dpkg.log
Prevenir en lugar de reparar
Para que el error no llegue a convertirse en un ladrón de tiempo, ayudan cuatro hábitos:
- Configura el timeout y aun así repite.
DPkg::Lock::Timeouten/etc/apt/apt.conf.d/99lock-timeouthace que apt espere en el bloqueo del frontend y en el de dpkg en lugar de abortar. Como el bloqueo de las descargas y el de las listas quedan fuera, en los scripts se añade un bucle de reintentos externo. Ambas cosas juntas cubren prácticamente todos los casos. - Nunca actualices en una sesión SSH simple. Si la conexión se corta durante
apt upgrade, dpkg se interrumpe en mitad del proceso. Lanza las actualizaciones largas dentro detmuxoscreen. Los fundamentos están en el artículo sobre cómo conectarte al servidor por SSH. - Evita Ctrl+C mientras tanto. Durante la descarga, interrumpir no tiene mayor importancia, pero durante la descompresión y la configuración genera justo esos paquetes a medio instalar del apartado anterior.
- No dejes que tus tareas de mantenimiento choquen con los timers del sistema. Quien programa una actualización propia debe planificarla desplazada en el tiempo y con timeout. Cómo configurarlo correctamente lo explican los artículos sobre cronjobs en Linux y sobre servicios systemd propios.
Y una advertencia más sobre la salida aparentemente más sencilla: apt remove unattended-upgrades elimina los conflictos de bloqueo, pero también te quita las actualizaciones de seguridad automáticas. En un servidor accesible desde internet es un mal negocio. Tiene mucho más sentido conservar la actualización automática y hacer que tus propios procesos sean pacientes.
En resumen: lsof sobre el archivo de bloqueo indicado, revisar la lista de procesos y esperar. Solo cuando esté demostrado que ya no queda nada en marcha, elimina los archivos de bloqueo y ejecuta después siempre dpkg --configure -a y apt-get check. Con DPkg::Lock::Timeout en la configuración de apt y un bucle de reintentos alrededor de apt-get update, el resto se resuelve solo.
Preguntas frecuentes
¿Puedo borrar sin más el archivo de bloqueo?
¿Cuánto tiempo debo esperar antes de intervenir?
¿Qué significa el nombre de proceso unattended-upgr en el mensaje de error?
¿Por qué necesito dpkg --configure -a después de eliminar el archivo de bloqueo?
¿Cómo evito este error en scripts y roles de Ansible?
¿Existe este error también en AlmaLinux o Rocky Linux?
Tras la reparación apt sigue dando errores en un solo paquete, ¿qué hago?
2026 KernelHost GmbH. Todos los derechos reservados. Esta guía está protegida por derechos de autor. Su publicación en otros sitios web, aunque sea de forma parcial o modificada, no está permitida sin nuestro consentimiento por escrito. Las citas con indicación de la fuente y un enlace son muy bienvenidas.

