SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Cómo recuperar una actualización de Ubuntu fallida

Si Ubuntu 24.04 a 26.04 se detuvo, vuelve a la sesión de screen, repara dpkg, corrige fuentes a medias y decide cuándo restaurar el snapshot.

La actualización de Ubuntu falló a mitad de camino: lea 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. Es posible que el actualizador siga ejecutándose dentro de una sesión de screen cuya conexión se perdió. Es posible que dpkg se haya terminado con un paquete a medio configurar, por lo que apt ahora rechaza cualquier operación que instale, elimine o actualice paquetes, aunque apt update y los comandos de sólo lectura como apt show sigan funcionando. Las fuentes de apt pueden indicar 26.04 mientras los paquetes instalados siguen siendo de 24.04. También es posible que el servidor no arranque. Determine cuál de estos estados tiene antes de escribir cualquier comando, porque la solución de un estado puede empeorar otro.

Una regla se aplica a los cuatro estados. 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 reparar en el caso de que el sistema no arranque, descrito al final de esta guía. Tampoco inicie un segundo 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 supone 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, lea la sección de arranque teniendo esto en cuenta, ya que la instantánea es la solución para el peor caso.

¿La actualización sigue en ejecución?

Muchas actualizaciones que se notifican 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 la que se usa en un servidor, se inicia dentro de una sesión de GNU screen. Así, la actualización sobrevive a la pérdida del terminal que la inició. Además, cuando detecta que se inició desde una sesión SSH, ofrece iniciar una segunda instancia de 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 detalles 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 usuario no la mostrará.

sudo screen -ls

screen -ls indica si cada sesión está asociada o separada. Si aparece una sesión, vuelva a asociarse a ella. Si todavía figura como asociada porque la conexión SSH perdida nunca la liberó, -d separa primero esa asociación obsoleta.

sudo screen -d -r

Si aparece más de una sesión, añada a -r el nombre de sesión mostrado por screen -ls. No confíe en que sudo do-release-upgrade vuelva a asociarla automáticamente. El código que busca su sesión de screen existente se encuentra en el actualizador que descarga. Antes de descargar nada, do-release-upgrade termina con el mensaje "Please install all available updates for your release before upgrading" cuando encuentra un paquete con una actualización pendiente (salvo las actualizaciones escalonadas). Ese es exactamente el estado de un sistema que está a mitad del reemplazo de paquetes. Cuando vuelva a asociarse, regresará a la actualización en ejecución. 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 asociarse 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 existe sólo mientras dura la actualización. Si no puede iniciar sesión mediante 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. sudo ufw status indica si el firewall permitió el paso por el 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 pasar a repararlo. Un proceso de dpkg o apt con mucho tiempo transcurrido y sin una sesión de screen a la que volver a asociarse está bloqueado. Espere unos minutos, compruebe si hay una pregunta de debconf sin responder en la consola y sólo entonces termine 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, el paquete queda marcado como parcialmente configurado y deja entradas sin terminar en su registro bajo /var/lib/dpkg/updates/. Todos los comandos de apt que toman el bloqueo de dpkg, es decir, los que instalan, eliminan o actualizan paquetes, comprueban primero ese registro y se detienen con dpkg was interrupted, you must manually run 'sudo dpkg --configure -a' to correct the problem.. Los comandos que nunca toman ese bloqueo, como apt update, apt list, apt show y apt-cache, siguen funcionando, por lo que todavía puede inspeccionar el sistema. Independientemente de lo demás que muestre apt, el primer paso es siempre el mismo.

sudo dpkg --configure -a

Esto completa 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 con una actualización incompleta, así que déjelo ejecutarse hasta 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 muestra cómo interpretar su error.

Después, deje que apt repare las dependencias que quedaron sin satisfacer debido a la interrupción, porque algunos paquetes se actualizaron pero los paquetes de los que dependen no.

sudo apt --fix-broken install

Después, complete la actualización que el actualizador estaba ejecutando:

sudo apt update
sudo apt full-upgrade

Use full-upgrade en lugar de upgrade, porque una actualización de versión elimina paquetes y upgrade sin opciones se niega a eliminar nada. Lea el resumen que muestra apt antes de confirmarlo. Una lista corta de eliminaciones es normal. No lo es una lista que elimine ubuntu-server, systemd, openssh-server o el paquete del kernel. En ese caso, responda que no y averigüe por qué apt quiere eliminarlos antes de continuar.

Compruebe el resultado antes de hacer cualquier otra cosa:

sudo dpkg --audit
sudo apt-get check

dpkg --audit muestra todos los paquetes que todavía están en un estado defectuoso y apt-get check informa de las dependencias no satisfechas. Ambos comandos deberían no mostrar nada. Cuando así sea, ejecute sudo apt autoremove para eliminar las dependencias instaladas automáticamente que ya no necesita ningún paquete (los paquetes marcados como instalados manualmente se conservan, aunque no los use nada). Después, confirme la versión con cat /etc/os-release, ejecute sudo update-initramfs -u -k all y sudo update-grub y reinicie sólo entonces.

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 tanto, 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 actualizador se bloqueó, aquí también aparece la traza de Python. Léalo desde el final: las últimas líneas indican la fase en la que se detuvo y una traza 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, lo que significa que 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 aparecido en pantalla. El último paquete que menciona antes del final es el que se estaba procesando cuando la actualización se detuvo. Si falló un script del mantenedor, la queja de dpkg aparece allí, junto con el error del propio 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 | tail

Compare esta información con /var/log/dpkg.log, que registra los cambios de estado y las acciones que realiza dpkg, cada una con una marca de tiempo. tail -n 30 /var/log/dpkg.log muestra el último paquete que procesó dpkg y qué operación estaba realizando. Es la misma respuesta obtenida de una segunda fuente sólo si ningún proceso ha ejecutado dpkg desde el fallo. Después de ejecutar dpkg --configure -a o apt --fix-broken install, sus entradas aparecen al final. Desplácese hacia atrás hasta las líneas cuya marca de tiempo coincida con el momento en que se detuvo la actualización.

La mayoría de los fallos de esta fase en un servidor se debe a una de varias causas. Un servicio que el paquete reinicia en su postinst no arranca porque usted personalizó su archivo de configuración. systemctl status y journalctl -xeu sobre ese servicio indican la línea que el servicio 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 lo muestra. sudo apt clean vacía la caché aunque apt esté bloqueado por otro motivo, y un disco que indica que está lleno aunque du diga que no lo está 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 incluye. Un paquete retenido (apt-mark showhold) puede haber impedido actualizar una dependencia. Corrija la causa y vuelva a ejecutar sudo dpkg --configure -a. El proceso continúa desde el punto en 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 -a

Use esto sólo con un paquete cuyo nombre y función pueda justificar. Nunca lo use con una biblioteca ni con nada de la cadena de dependencias ubuntu-server, porque la eliminación forzada omite las comprobaciones que indicarían qué otros componentes se romperían.

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 por eso do-release-upgrade puede insistir ahora en que no hay ninguna versión nueva.

Compare los dos lugares que indican qué versión está instalada. /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-files

Hay tres combinaciones importantes. Si las fuentes todavía indican 24.04 (nombre en clave noble) y os-release todavía indica 24.04, la actualización no superó sus comprobaciones. Puede ejecutar sudo do-release-upgrade de nuevo después de leer main.log para saber por qué se detuvo. Se niega a iniciarse mientras haya alguna actualización de 24.04 pendiente o mientras /var/run/reboot-required.pkgs indique libc6, linux-base o un paquete linux-image. Por tanto, ejecute sudo apt full-upgrade y reinicie si ese archivo lo solicita primero. Si las fuentes indican el nombre en clave de 26.04 y os-release todavía indica 24.04, el reemplazo de paquetes comenzó y se interrumpió. La reparación de dpkg de la sección anterior, que termina con apt full-upgrade, es la forma de completarlo. No vuelva a ejecutar el actualizador en este estado. Como hay paquetes de 26.04 pendientes, se detendrá y le pedirá que instale primero todas las actualizaciones disponibles. Si las fuentes indican 26.04 y os-release indica 26.04, base-files fue uno de los paquetes que llegó a instalarse. El sistema ahora se identifica como 26.04, aunque la mayoría de sus componentes no lo sean.

La última combinación es la problemática. do-release-upgrade determina la versión instalada 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 una versión nueva disponible. La herramienta está respondiendo a una pregunta sobre os-release, y os-release es incorrecto. No siga ejecutando el actualizador. Termine la actualización con apt: sudo apt update y después sudo apt full-upgrade. Este último actualiza los paquetes que todavía tienen la versión de 24.04, excepto los que están retenidos (apt-mark showhold los muestra), y puede eliminar algunos paquetes en su lugar. Lea el resumen y ejecute después sudo apt autoremove. También conviene descartar los otros motivos por los que do-release-upgrade informa de que no hay una versión nueva, como una solicitud de LTS que espera a la primera versión de mantenimiento, 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 seguridad de cada archivo que modifica, añadiendo un sufijo al nombre original. Ejecute ls -la /etc/apt/sources.list.d/ y diff para comparar cada archivo original con su copia de seguridad y 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 indica que una fuente está configurada más de una vez, una entrada sources.list antigua y la nueva entrada ubuntu.sources describen la misma suite. 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 -a

Si 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
reboot

Antes 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 una interrupción?

No como primera medida. Si el actualizador sigue activo en su sesión de screen, vuelva a conectarse con sudo screen -d -r. Un segundo do-release-upgrade se detiene antes de llegar a su propio código de reconexión porque no se inicia mientras haya algún paquete con una actualización pendiente. Si el actualizador se ha detenido, ejecute primero sudo dpkg --configure -a y sudo apt --fix-broken install. Si las fuentes ya indican 26.04, complete el proceso con sudo apt full-upgrade en lugar de usar el actualizador. Si todavía indican 24.04, ejecute sudo apt full-upgrade, reinicie si /var/run/reboot-required.pkgs muestra libc6, linux-base o un kernel, y después vuelva a iniciar el actualizador. También se detiene si Prompt=never está establecido en /etc/update-manager/release-upgrades o si el servidor de Ubuntu responde "Release upgrade not possible right now".

¿Por qué do-release-upgrade indica que no hay una versión nueva después de que falle la actualización?

Porque base-files, el paquete que escribe /etc/os-release, fue uno de los paquetes actualizados antes de la interrupción. La herramienta ahora lee ese archivo, concluye que está en 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 complete el proceso con sudo apt update && sudo apt full-upgrade.

¿Es seguro reiniciar un servidor Ubuntu con una actualización a medias?

No hasta que sudo dpkg --audit no devuelva nada. Reiniciar con un kernel desempaquetado pero no configurado, o sin regenerar GRUB, es la causa más habitual de que una actualización que podía repararse en diez minutos termine requiriendo una imagen de rescate. Complete la reparación de dpkg y apt full-upgrade, ejecute update-initramfs -u -k all y update-grub, y sólo entonces reinicie.

¿Cómo puedo saber 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 de que termine el registro es el que se estaba procesando. Un script de mantenimiento fallido muestra su error justo encima del mensaje de dpkg. /var/log/dpkg.log es una segunda fuente de información: sus líneas con la marca de tiempo de la detención de la actualización indican el mismo paquete. Sin embargo, todo lo que haya ejecutado mediante dpkg desde entonces se registra después, por lo que sus últimas líneas pueden no corresponder. 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 atascado, cuando no tenga acceso a la consola o cuando el servidor deba volver a estar disponible rápidamente. Siga reparando sólo cuando sepa exactamente qué se rompió y la solución sea un único comando. Copie /var/log/dist-upgrade/ fuera del servidor antes de restaurar la instantánea; de lo contrario, el segundo intento fallará de la misma manera.