Cómo recuperar una actualización de Ubuntu fallida
Si la actualización de Ubuntu 24.04 a 26.04 se detuvo, reconecte screen, repare dpkg y las fuentes de apt, o restaure el snapshot si no arranca.
La actualización de Ubuntu falló a mitad de camino: revise primero el síntoma
Una actualización de versión de Ubuntu de 24.04 a 26.04 que falla deja el servidor en uno de cuatro estados, y cada estado requiere una solución distinta. El actualizador puede seguir ejecutándose dentro de una sesión de screen con la que perdió la conexión. Es posible que dpkg haya sido terminado con un paquete a medio configurar, por lo que apt ahora rechaza todos los comandos. Las fuentes de apt pueden indicar 26.04 mientras los paquetes instalados siguen siendo de 24.04. O puede que el servidor no arranque. Determine cuál de estos estados tiene antes de escribir nada, porque la solución de un estado puede empeorar otro.
Una regla se aplica a los cuatro casos. No reinicie hasta saber en qué estado se encuentra dpkg. Reiniciar durante el intercambio de paquetes es lo que convierte una interrupción de dpkg que se puede corregir en el caso de que el sistema no arranque, descrito al final de esta guía. Tampoco inicie otro proceso de apt o dpkg mientras el primero pueda seguir activo, porque dos procesos escribiendo en la base de datos de paquetes pueden corromperla.
Esta guía presupone que siguió la guía de actualización de 24.04 a 26.04 y creó una instantánea antes de comenzar. Si no lo hizo, tenga esto en cuenta al leer la sección sobre el arranque, ya que la instantánea es la solución para el peor caso.
¿La actualización sigue ejecutándose?
Muchas actualizaciones que aparecen como fallidas siguen ejecutándose. La sesión SSH se desconectó, el terminal quedó en blanco y el actualizador continuó sin usted.
do-release-upgrade está diseñado para este caso. Cuando se ejecuta con su interfaz de texto, que es lo que usa un servidor, se inicia dentro de una sesión de GNU screen. Así, la actualización sobrevive a la pérdida del terminal desde el que se inició. Además, cuando detecta que se inició desde una sesión SSH, ofrece iniciar un segundo sshd en otro puerto (1022 de forma predeterminada). De este modo, todavía puede iniciar sesión si el daemon SSH principal falla durante el reemplazo de paquetes. Ambos datos son importantes ahora.
Vuelva a conectarse mediante SSH y busque la sesión de screen. El actualizador se ejecutó con sudo, por lo que su sesión de screen pertenece a root. Un screen -ls ejecutado como su propio usuario no la mostrará.
sudo screen -lsscreen -ls indica si cada sesión está conectada o desconectada. Si aparece una sesión, vuelva a conectarse a ella. Si todavía figura como conectada porque la conexión SSH interrumpida nunca la liberó, -d desconecta primero esa conexión obsoleta.
sudo screen -d -rSi aparecen varias sesiones, añada el nombre de sesión de screen -ls después de -r. Ejecutar sudo do-release-upgrade de nuevo también funciona: el actualizador comprueba si ya existe su propia sesión de screen y vuelve a conectarse a ella en lugar de iniciar una ejecución nueva. En ambos casos, volverá a la actualización en curso. Normalmente estará esperando una respuesta sobre un archivo de configuración modificado o el reinicio de un servicio. Responda y deje que termine.
Si inició la actualización dentro de tmux, como recomienda la guía de actualización, vuelva a conectarse primero a tmux con tmux attach. La sesión de screen se ejecuta dentro de ese panel de tmux, por lo que verá directamente la actualización. Si el panel sólo muestra un indicador de shell, el actualizador ya no se está ejecutando allí y sudo screen -ls es la siguiente comprobación.
Si el puerto SSH principal rechaza la conexión, pruebe el puerto alternativo: ssh -p 1022 user@host. Ese daemon sólo existe durante la actualización. Si no puede acceder por ninguno de los dos puertos, use la consola de su proveedor. Desde la consola, sudo ss -ltnp muestra en qué puertos está escuchando un proceso sshd, y sudo ufw status indica si el firewall permitió el acceso al puerto alternativo.
Si no existe ninguna sesión de screen y no hay nada esperando en la consola, la actualización realmente se detuvo. Confirme que ningún proceso siga trabajando con la base de datos de paquetes antes de modificarla:
ps -eo pid,etime,cmd | grep -iE '[u]pgrade|[d]pkg|[a]pt'Un resultado vacío significa que dpkg está inactivo y puede continuar con la reparación. Un proceso de dpkg o apt con mucho tiempo transcurrido y sin una sesión de screen a la que volver a conectarse está bloqueado. Espere unos minutos, compruebe si hay una pregunta de debconf sin responder en la consola y sólo entonces finalice el proceso. Nunca elimine los archivos de bloqueo de /var/lib/dpkg/ o /var/lib/apt/lists/ mientras un proceso los tenga abiertos. El bloqueo es lo único que impide que dos procesos de escritura corrompan la base de datos de paquetes.
dpkg fue interrumpido y apt se niega a ejecutarse
Cuando se termina dpkg entre la extracción de un paquete y la ejecución de su script de configuración, registra ese estado incompleto en /var/lib/dpkg/status. Todos los comandos posteriores de apt leen ese estado y se detienen, porque apt no puede continuar sobre una base de datos con trabajo pendiente. Independientemente del mensaje que muestre apt al rechazar la operación, el primer paso es el mismo.
sudo dpkg --configure -aEsto termina la configuración de todos los paquetes que se extrajeron pero nunca se configuraron. Ejecuta los scripts del mantenedor en orden de dependencias y puede tardar mucho en un sistema cuya actualización quedó a medias, así que espere a que termine. Si se detiene en un paquete, muestra el nombre del paquete y el script que falló. Anote ese nombre. Es el paquete que detuvo la actualización, y la sección siguiente explica cómo leer su error.
Después, deje que apt repare las dependencias no satisfechas que dejó la interrupción, porque algunos paquetes se actualizaron pero los paquetes de los que dependen no.
sudo apt --fix-broken installDespués, termine la actualización que el actualizador estaba ejecutando:
sudo apt update
sudo apt full-upgradeUse full-upgrade en lugar de upgrade, porque una actualización de versión elimina paquetes y upgrade sin opciones se niega a eliminar ninguno. Lea el resumen que muestra apt antes de confirmar. Una lista breve de eliminaciones es normal. Si la lista elimina ubuntu-server, systemd, openssh-server o el paquete del kernel, no lo es. Responda que no y averigüe por qué apt quiere hacerlo antes de continuar.
Compruebe el resultado antes de hacer cualquier otra cosa:
sudo dpkg --audit
sudo apt-get checkdpkg --audit muestra todos los paquetes que todavía están en un estado incorrecto y apt-get check informa de las dependencias no satisfechas. Ambos comandos deberían no mostrar nada. Cuando no muestren nada, ejecute sudo apt autoremove para eliminar los paquetes de 24.04 de los que ya no depende ningún paquete. Después, confirme la versión con cat /etc/os-release, ejecute sudo update-initramfs -u -k all y sudo update-grub y, sólo entonces, reinicie el sistema.
Cómo leer /var/log/dist-upgrade para encontrar el paquete que detuvo la actualización
El actualizador escribe todo en /var/log/dist-upgrade/. Si lo ha ejecutado más de una vez, mueve los registros del intento anterior a un subdirectorio cuyo nombre contiene una marca de tiempo. Por eso, compruebe primero ls -la /var/log/dist-upgrade/ y lea el directorio que corresponda a la ejecución fallida.
main.log es el registro propio del actualizador. Indica en qué fase estaba la ejecución y qué decidió sobre las fuentes de paquetes. Si el propio actualizador se bloqueó, aquí también aparece el traceback de Python. Léalo desde el final: las últimas líneas indican la fase en la que se detuvo. Si aparece un traceback, significa que falló la herramienta, no un paquete.
apt.log contiene el razonamiento del resolvedor de dependencias. Es detallado y resulta importante cuando apt se negó a calcular la actualización, es decir, cuando el fallo ocurrió antes de tocar ningún paquete. Si la actualización llegó a instalar paquetes, normalmente puede omitirlo.
apt-term.log es el archivo que necesita para investigar un fallo de paquete. Captura la salida del terminal de dpkg durante la actualización, el mismo texto que habría pasado por la pantalla. El último paquete que menciona antes del final es el que se estaba procesando cuando se detuvo la actualización. Si falló un script del mantenedor, la queja de dpkg aparece allí, junto con el error propio del script justo encima.
sudo tail -n 60 /var/log/dist-upgrade/apt-term.log
sudo grep -in 'error' /var/log/dist-upgrade/apt-term.log | tailCompare el resultado con /var/log/dpkg.log, que registra cada cambio de estado que realiza dpkg junto con una marca de tiempo. tail -n 30 /var/log/dpkg.log muestra el último paquete que procesó dpkg y la operación que estaba realizando, lo que proporciona la misma respuesta desde una segunda fuente.
En esta fase, la mayoría de los fallos en un servidor se deben a unas pocas causas. Un servicio que el paquete reinicia en su postinst no arranca porque contiene un archivo de configuración personalizado. systemctl status y journalctl -xeu sobre ese servicio indican la línea que no acepta. También puede haberse llenado un sistema de archivos, normalmente /boot con kernels antiguos o /var con la caché de paquetes de apt. df -h / /boot /var muestra esta situación. sudo apt clean vacía la caché aunque apt esté bloqueado, y un disco que indica que está lleno aunque du diga que no tiene su propia explicación. Un paquete de un repositorio de terceros que el actualizador deshabilitó puede depender de una biblioteca que 26.04 ya no distribuye. Un paquete retenido (apt-mark showhold) puede haber impedido actualizar una dependencia. Corrija la causa y vuelva a ejecutar sudo dpkg --configure -a. El comando continuará desde el punto en el que se detuvo.
Si un paquete se niega a configurarse haga lo que haga y ningún componente importante depende de él, elimínelo y vuelva a instalarlo cuando termine la actualización:
sudo dpkg --remove --force-remove-reinstreq package-name
sudo dpkg --configure -aUse esto sólo con un paquete cuyo nombre y función pueda explicar. Nunca lo use con una biblioteca ni con nada de la cadena de dependencias de ubuntu-server, porque la eliminación forzada omite las comprobaciones que indicarían qué otros componentes dejarían de funcionar.
Las fuentes cambiaron, pero los paquetes no
El actualizador reescribe las fuentes de apt al principio, antes de descargar paquetes. Si se interrumpe después de ese punto, las fuentes indican 26.04, mientras que los paquetes instalados son una mezcla. Esa mezcla confunde a las herramientas y explica por qué do-release-upgrade puede insistir ahora en que no existe ninguna versión nueva.
Compare los dos lugares que indican en qué versión está. /etc/apt/sources.list.d/ubuntu.sources es el archivo de fuentes deb822 que introdujo 24.04, y sus líneas Suites: contienen el nombre en clave de la versión. /etc/os-release lo escribe el paquete base-files e indica qué versión está instalada realmente.
grep -E '^(Suites|Components):' /etc/apt/sources.list.d/ubuntu.sources
grep -E '^(VERSION_ID|VERSION_CODENAME)=' /etc/os-release
apt-cache policy base-filesImportan tres combinaciones. Las fuentes todavía indican 24.04 (nombre en clave noble) y os-release también indica 24.04: la actualización no superó sus comprobaciones, y puede ejecutar sudo do-release-upgrade de nuevo después de leer main.log para saber por qué se detuvo. Las fuentes indican el nombre en clave de 26.04, pero os-release todavía indica 24.04: comenzó el reemplazo de paquetes y se interrumpió, y la reparación de dpkg de la sección anterior, que termina con apt full-upgrade, es la forma de completarlo. Las fuentes indican 26.04 y os-release indica 26.04: base-files fue uno de los paquetes que llegó a instalarse, y el sistema ahora se identifica como 26.04 aunque la mayor parte del sistema no lo sea.
La última combinación es la problemática. do-release-upgrade determina en qué versión está a partir de la misma información que contiene os-release. Si os-release ya indica 26.04, la herramienta busca una versión posterior a 26.04, no encuentra ninguna e informa de que no hay ninguna versión nueva disponible. La herramienta responde a una pregunta sobre os-release, y os-release contiene un valor incorrecto. No siga ejecutando el actualizador y termine con apt: sudo apt update y después sudo apt full-upgrade, que actualiza todos los paquetes que todavía tienen la versión de 24.04, y luego sudo apt autoremove. También conviene descartar otros motivos por los que do-release-upgrade informa de que no hay ninguna versión nueva, como un aviso para cambiar a una versión LTS que espera a la primera actualización de punto, si os-release todavía indica 24.04.
El actualizador también deshabilita las fuentes de terceros en /etc/apt/sources.list.d/ y conserva una copia de respaldo de cada archivo que modifica, añadiendo un sufijo al nombre original. Ejecute ls -la /etc/apt/sources.list.d/ y diff sobre cada archivo original y su copia de respaldo para ver exactamente qué cambios realizó. Mantenga deshabilitadas las entradas de terceros hasta que los paquetes de Ubuntu sean coherentes. Después, vuelva a habilitar cada una sólo tras confirmar que el proveedor publica paquetes para 26.04. Si apt update informa de que una fuente está configurada más de una vez, una entrada sources.list antigua y la entrada ubuntu.sources nueva describen la misma suite, y el error de fuente duplicada de deb822 explica cuál debe eliminar.
El servidor no arranca después de la actualización
Un reinicio revela el coste de una actualización incompleta. En un VPS, las causas más probables son un kernel instalado sin su initramfs, una configuración de GRUB que nunca se regeneró, un paquete que quedó configurado parcialmente y del que depende una unidad durante el arranque, o un disco que se llenó mientras dpkg escribía.
Abra la consola del proveedor antes de hacer cualquier otra cosa. Le muestra dónde se detiene el arranque: en el menú de GRUB, por un kernel panic, durante una comprobación del sistema de archivos que espera una respuesta o en un shell de emergencia de systemd que solicita la contraseña de root. Esta observación determina el siguiente paso.
Si aparece GRUB, arranque el kernel anterior de 24.04 desde el submenú de opciones avanzadas. El kernel antiguo normalmente permanece instalado hasta que se ejecuta autoremove. Cuando el sistema esté funcionando con el kernel antiguo, ejecute sudo dpkg --configure -a y el resto de la reparación de la sección anterior. Después ejecute sudo update-initramfs -u -k all y sudo update-grub antes de volver a probar el kernel nuevo. Recuperar un VPS que no arranca después de actualizar el kernel explica con detalle la parte de GRUB e initramfs.
Si llega a un shell de emergencia, el sistema de archivos raíz normalmente está montado como de solo lectura. Vuelva a montarlo y ejecute la misma reparación:
mount -o remount,rw /
dpkg --configure -aSi el sistema no llega a ningún shell, arranque la imagen de rescate del proveedor, monte el disco del VPS y repare desde un chroot. Busque la partición raíz con lsblk en lugar de adivinar su nombre.
lsblk
mount /dev/<root-partition> /mnt
for d in dev proc sys run; do mount --bind /$d /mnt/$d; done
chroot /mnt /bin/bash
dpkg --configure -a
apt --fix-broken install
update-initramfs -u -k all
update-grub
exit
rebootAntes de pasar una hora en ese chroot, compare esta opción con la instantánea. Creó una antes de empezar y, en la mayoría de los proveedores, restaurarla tarda unos minutos. Después puede volver a ejecutar la actualización, que en un VPS tarda bastante menos de una hora, y esta vez sabrá de antemano qué paquete debe reparar. Restaurar es la opción más rápida cuando se cumple cualquiera de estas condiciones: no puede acceder a una consola ni a una imagen de rescate, no puede identificar el paquete que detuvo la actualización, hay más de un paquete bloqueado o el servidor ejecuta servicios que otras personas están esperando. La reparación manual sólo es más rápida cuando sabe exactamente qué falló y la solución consiste en ejecutar un único comando.
Copie /var/log/dist-upgrade/ fuera del servidor antes de restaurar, desde la imagen de rescate si es la única forma de acceder. La restauración borra esos registros, y un segundo intento fallará exactamente de la misma manera si nunca averiguó por qué falló el primero. Qué puede restaurar una instantánea y qué no merece una lectura antes de depender de una. Una instantánea revierte todo el disco, incluidos los datos escritos desde que la creó. Esto es adecuado durante una actualización, pero no una semana después.
Tres señales de que conviene reconstruir el sistema
Algunas actualizaciones no merecen la pena. Restaurar una instantánea y volver a ejecutar el proceso es barato, pero si el fallo se debe al estado del propio sistema, la segunda ejecución también falla. En ese caso, la solución correcta es usar una imagen nueva de 26.04 y restaurar los datos desde una copia de seguridad. Tres señales indican que ha llegado a ese punto.
La primera es que la base de datos del propio dpkg está dañada. Si dpkg --audit o apt-get check no pueden leer /var/lib/dpkg/status en absoluto, en lugar de informar de paquetes dañados dentro de ella, se ha perdido el registro de lo instalado. Ubuntu conserva copias diarias en /var/backups/ (ls -la /var/backups/dpkg.status*), y a veces funciona sustituirla por la copia correcta más reciente. Pero cuando esa copia ya no coincide con lo que realmente hay en el disco, estaría trabajando a ciegas, y cada ejecución posterior de apt se basaría en esa suposición.
La segunda es que las herramientas necesarias para reparar el sistema también están dañadas. Si apt o dpkg no se inician porque se eliminó o sustituyó parcialmente una biblioteca compartida, o systemd no puede iniciar unidades porque su propio paquete está configurado a medias, ya no hay un gestor de paquetes operativo que pueda reparar el gestor de paquetes. ldd /usr/bin/apt indica si están presentes todas las bibliotecas de apt. A veces puede recuperarse el sistema desde un chroot en la imagen de rescate, pero normalmente ese proceso tarda más que reconstruirlo.
La tercera es que la lista de paquetes dañados no se reduce. Si ha ejecutado dpkg --configure -a y apt --fix-broken install en un bucle durante más de una hora, y cada pasada descubre un paquete nuevo en lugar de resolver el anterior, el sistema ya tenía problemas antes de la actualización y esta no los creó: archivos de /usr modificados manualmente, paquetes fijados o retenidos, un repositorio de terceros que sustituyó bibliotecas esenciales, o una actualización anterior que nunca llegó a completarse. Una imagen nueva no tiene esos problemas, y restaurar los datos en ella tarda menos que localizarlos.
Una reconstrucción sólo es rápida si los datos están almacenados en otro lugar. Esa es la diferencia entre una instantánea y una copia de seguridad, y el motivo por el que la guía de actualización solicita ambas.
FAQ
¿Puedo ejecutar do-release-upgrade de nuevo después de que se haya interrumpido?
Sí. Es la primera medida recomendada. Si el actualizador sigue activo en su sesión de screen, ejecutarlo de nuevo vuelve a conectarse a esa sesión. Si ya no está activo, ejecute sudo dpkg --configure -a y sudo apt --fix-broken install primero y, después, inicie de nuevo el actualizador. Este vuelve a leer el estado actual y continúa. La única situación en la que no puede ayudar es cuando /etc/os-release ya muestra 26.04, porque entonces considera que la actualización ha terminado. En ese caso, finalice con sudo apt full-upgrade.
¿Por qué do-release-upgrade indica que no hay ninguna versión nueva después de que la actualización haya fallado?
Porque base-files, el paquete que escribe /etc/os-release, fue uno de los paquetes que se actualizaron antes de la interrupción. La herramienta ahora lee ese archivo, concluye que está usando 26.04 y no encuentra ninguna versión posterior que ofrecer. Compare grep VERSION_ID /etc/os-release con grep Suites /etc/apt/sources.list.d/ubuntu.sources y, después, finalice con sudo apt update && sudo apt full-upgrade.
¿Es seguro reiniciar un servidor Ubuntu cuya actualización ha quedado a medias?
No hasta que sudo dpkg --audit no devuelva ningún resultado. Reiniciar con un kernel desempaquetado pero no configurado, o sin haber regenerado GRUB, es la forma más habitual de convertir una actualización que podía repararse en diez minutos en una tarea de recuperación mediante una imagen de rescate. Complete la reparación de dpkg y apt full-upgrade, ejecute update-initramfs -u -k all y update-grub y reinicie sólo después.
¿Cómo averiguo qué paquete detuvo la actualización?
Lea el final de /var/log/dist-upgrade/apt-term.log, que contiene la salida final de dpkg. El último paquete mencionado antes del final del registro es el que se estaba procesando, y un script de mantenimiento que falla muestra su error justo encima del mensaje de error de dpkg. tail -n 30 /var/log/dpkg.log lo confirma desde una segunda fuente. Si, en cambio, main.log termina con un traceback de Python, el propio actualizador se bloqueó y ningún paquete es responsable.
¿Debo restaurar la instantánea o seguir reparando?
Restaure cuando no pueda identificar el paquete que falló, cuando haya más de un paquete bloqueado, cuando no tenga acceso a la consola o cuando el servidor deba volver a estar disponible rápidamente. Siga reparando sólo cuando conozca exactamente qué falló y la solución consista en un único comando. Copie /var/log/dist-upgrade/ fuera del servidor antes de restaurar. De lo contrario, el segundo intento fallará de la misma manera.