Debian 13: APT está roto (“dependencias incumplidas”) — arréglalo sin reinstalar nada

¿Te fue útil?

Ejecutas apt upgrade y Debian responde con ese clásico, pasivo-agresivo lema: “dependencias incumplidas”. Ahora nada se instala, la mitad de tus paquetes están “retenidos” y tu terminal parece juzgar tus decisiones de vida.

Esto tiene solución. Casi siempre. Y puedes arreglarlo sin reinstalar Debian, sin “simplemente usa Docker” y sin explorar a ciegas montones de hilos de foro. Diagnostiquemos qué está realmente roto (fuentes, pins, retenciones, estado de dpkg o una actualización parcial) y luego repáralo con pasos deliberados que puedas explicar a una junta de revisión de cambios.

Qué significa realmente “dependencias incumplidas” (y qué no significa)

APT no está “roto” porque imprima un error. Está roto porque APT no puede encontrar un conjunto consistente de versiones de paquetes que satisfagan:

  • Lo que pediste (instalar/actualizar/eliminar),
  • Lo que ya está instalado,
  • Lo que ofrecen tus repositorios,
  • Y lo que tu política permite (pins, prioridades, paquetes “retenidos”).

En la práctica, “dependencias incumplidas” suele reducirse a una de estas:

  1. Repositorios mixtos: tienes Debian stable + testing + unstable, o un repo de terceros compilado para otra versión de Debian. APT no es terapeuta; no puede reconciliar compromisos contradictorios.
  2. Actualización parcial: algunos paquetes avanzaron a versiones más nuevas pero su cadena de dependencias no lo hizo, a menudo por actualizaciones interrumpidas, paquetes retenidos o disponibilidad cambiante de repositorios.
  3. Estado de dpkg inconsistente: paquetes sin configurar, medio instalados o diversiones alteradas. APT delega el desempaquetado/configuración a dpkg; si dpkg está atascado, APT también lo está.
  4. Paquetes retenidos: una biblioteca central está retenida, por lo que todo lo que depende de ella no puede moverse.
  5. Pinning (preferencias) ha hecho que tu sistema “elija” una versión que ya no existe en los repositorios habilitados.
  6. Rarezas de arquitectura y multiarch: mezclar i386/amd64 sin intención, o paquetes de arquitecturas extrañas obsoletas.

Lo que no es: una razón para reinstalar, una excusa para empezar a borrar paquetes al azar, o una invitación a aporrear apt --fix-broken install hasta que te dé la razón. Usaremos esa herramienta, pero solo cuando entendamos qué va a hacer.

Guía rápida de diagnóstico (primero/segundo/tercero)

Si esto es algo parecido a producción, quieres señal rápido. Aquí tienes un orden de triaje que funciona porque separa “APT no puede calcular una solución” de “dpkg no puede aplicar la solución”.

Primero: confirma el modo de fallo

  • ¿Puede APT calcular un plan pero dpkg falla al aplicarlo? (lock de dpkg, configuración interrumpida, script de mantenedor roto)
  • ¿O APT no puede calcular un plan en absoluto? (mezcla de repos, pins, retenciones, versiones faltantes)

Segundo: valida repositorios y alineación de la release

  • Confirma que realmente estás en Debian 13 y que tus fuentes apuntan a Debian 13 (o su nombre en clave), de forma coherente.
  • Busca repos de terceros apuntando a la suite equivocada.
  • Busca testing/unstable habilitados por accidente.

Tercero: identifica qué bloquea el grafo de dependencias

  • Paquetes retenidos.
  • Pinning/preferencias (incluyendo pins de “origin” de repos de terceros).
  • Un paquete “clave” (a menudo libc6, libstdc++, openssl, systemd) que está atascado en una versión incompatible.

Cuarto: arregla el estado de dpkg si es necesario

  • Configura paquetes desempaquetados.
  • Resuelve scripts de mantenedor rotos.
  • Limpia locks con cuidado (rara vez necesario, pero cuando lo es, lo es).

Quinto: aplica una actualización completa controlada

  • Una vez que los repos y la política sean coherentes, haz un full-upgrade (o el equivalente moderno) para permitir que APT realice las eliminaciones/instalaciones necesarias.
  • Revisa las eliminaciones como si fueras a firmar una orden de compra.

Datos interesantes y contexto (lo que importa a las 2 a.m.)

  1. APT es más antiguo que la mayoría de herramientas cloud. El proyecto APT data de finales de los 90; su diseño asumía redes poco fiables y mirrors lentos, por eso es exigente con la consistencia y los metadatos.
  2. dpkg precede a APT. dpkg realiza la instalación/desempaquetado/configuración; APT es el planificador y descargador. Si dpkg está atascado, APT solo puede quejarse educadamente.
  3. “Depends” no es toda la historia. Los paquetes Debian también usan Pre-Depends, que fuerza el orden de instalación y puede hacer que el sistema se sienta “bloqueado” si un paquete central no puede transicionar.
  4. “Stable” es una promesa, no una propiedad mágica. Debian stable busca compatibilidad, pero si mezclas suites (stable/testing/unstable), renuncias a esa promesa.
  5. El pinning es tanto bisturí como motosierra. Las preferencias de APT fueron diseñadas para permitir mezcla controlada (como repos de seguridad o backports), pero un solo pin incorrecto puede congelar medio sistema.
  6. Los repos de terceros apuntan frecuentemente a Ubuntu primero. Muchos proveedores publican paquetes Debian, pero sus asunciones de dependencias a menudo se alinean con releases de Ubuntu, y así es como aparece “Depends: libsslX (>= …) pero no es instalable”.
  7. Los archivos Release son un límite de confianza. APT usa metadatos firmados de repositorios. Cuando las firmas fallan (clave expirada, suite equivocada), APT rechazará actualizaciones—lo que puede provocar indirectamente dependencias incumplidas durante upgrades.
  8. Multiarch no siempre existió. Mezclar arquitecturas se generalizó más tarde; paquetes i386 residuales en amd64 pueden crear restricciones de dependencias que parecen no relacionadas.
  9. “Retenido” suele ser APT siendo precavido. APT evita eliminaciones por defecto; una actualización puede requerir transiciones de paquetes que solo full-upgrade aceptará.

Antes de tocar nada: medidas de seguridad

Si esto es un portátil, tu “radio de impacto” es mayormente tu propia tarde. Si es un servidor, querrás movimientos reversibles.

  • Inicia un shell root con registro. Querrás una transcripción cuando luego expliques qué cambió.
  • Haz snapshot si puedes. Snapshot LVM, snapshot ZFS o snapshot de VM. Si no tienes ninguno, al menos copia /etc/apt y /var/lib/dpkg.
  • No elimines paquetes críticos a ciegas. Si APT propone eliminar systemd, ssh, libc6 o el meta-paquete del kernel, detente y entiende por qué.

Una verdad seca de operaciones: las soluciones “rápidas” que no puedes explicar son solo incidentes futuros entregados con antelación.

Idea parafraseada de Richard Cook (ingeniería de la resiliencia): “El éxito y el fracaso a menudo provienen del mismo trabajo cotidiano; no son mundos separados.”

Tareas prácticas de reparación (comandos, salidas, decisiones)

A continuación hay tareas concretas. Cada una incluye: comando, salida realista, qué significa y qué decisión tomar a continuación. Hazlas en orden a menos que ya sepas en qué modo de fallo estás.

Tarea 1: Confirma la versión del sistema operativo y el nombre en clave

cr0x@server:~$ cat /etc/os-release
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
NAME="Debian GNU/Linux"
VERSION_ID="13"
VERSION="13 (trixie)"
VERSION_CODENAME=trixie
ID=debian
HOME_URL="https://www.debian.org/"
SUPPORT_URL="https://www.debian.org/support"
BUG_REPORT_URL="https://bugs.debian.org/"

Significado: Estás en Debian 13, nombre en clave trixie. Las fuentes deben coincidir con las suites de Debian 13 (típicamente trixie, trixie-updates, trixie-security).

Decisión: Si tus fuentes hacen referencia a otro nombre en clave (como bookworm, sid o nombres de Ubuntu), corrige las fuentes primero. No intentes “forzar instalaciones” para salir del problema.

Tarea 2: Lista las fuentes APT, incluyendo deb822 y archivos legacy

cr0x@server:~$ find /etc/apt/sources.list /etc/apt/sources.list.d -maxdepth 1 -type f -print -exec sed -n '1,160p' {} \;
/etc/apt/sources.list
deb http://deb.debian.org/debian trixie main contrib non-free non-free-firmware
deb http://deb.debian.org/debian trixie-updates main contrib non-free non-free-firmware
deb http://security.debian.org/debian-security trixie-security main contrib non-free non-free-firmware
/etc/apt/sources.list.d/vendor.list
deb http://packages.vendor.example/debian bookworm main

Significado: Tienes un repo de terceros apuntando a bookworm (Debian 12) en un sistema Debian 13. Esa es una causa principal de dependencias incumplidas o degradaciones.

Decisión: Deshabilita o corrige ese repo antes de hacer cualquier otra cosa. Si el proveedor no soporta Debian 13, o reemplazas el software o aceptas que haces cirugía de dependencias sin soporte.

Tarea 3: Actualiza las listas de paquetes y lee los errores como evidencia

cr0x@server:~$ sudo apt update
Hit:1 http://deb.debian.org/debian trixie InRelease
Hit:2 http://deb.debian.org/debian trixie-updates InRelease
Hit:3 http://security.debian.org/debian-security trixie-security InRelease
Get:4 http://packages.vendor.example/debian bookworm InRelease [3,215 B]
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

Significado: APT descargó felizmente metadatos tanto de Debian 13 como del repo del proveedor en Debian 12. “All packages are up to date” solo significa que los metadatos están frescos, no que tu sistema sea consistente.

Decisión: Continúa con la inspección de la política. No actualices aún.

Tarea 4: Comprueba de qué suites APT cree que puede instalar (vista de políticas)

cr0x@server:~$ apt-cache policy | sed -n '1,80p'
Package files:
 100 /var/lib/dpkg/status
     release a=now
 500 http://packages.vendor.example/debian bookworm InRelease
     release o=Vendor,a=bookworm,n=bookworm,l=Vendor,c=main,b=amd64
 500 http://security.debian.org/debian-security trixie-security InRelease
     release o=Debian,a=trixie-security,n=trixie-security,l=Debian-Security,c=main,b=amd64
 500 http://deb.debian.org/debian trixie-updates InRelease
     release o=Debian,a=trixie-updates,n=trixie-updates,l=Debian,c=main,b=amd64
 500 http://deb.debian.org/debian trixie InRelease
     release o=Debian,a=trixie,n=trixie,l=Debian,c=main,b=amd64

Significado: El repo del proveedor tiene prioridad igual (500) que Debian. Eso significa que APT podría seleccionar paquetes del proveedor cuando las versiones parezcan “mejores”, trayendo dependencias que no existen en Debian 13.

Decisión: Si el repo del proveedor no coincide, deshabilítalo ahora; si es correcto pero demasiado “atractivo”, ponle un pin más bajo o limita su alcance a paquetes específicos.

Tarea 5: Identifica el conflicto exacto de dependencias

cr0x@server:~$ sudo apt install vendor-agent
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 vendor-agent : Depends: libssl3 (>= 3.0.0) but it is not installable
               Depends: libc6 (>= 2.37) but 2.36-9 is to be installed
E: Unable to correct problems, you have held broken packages.

Significado: El paquete requiere un libc6 más nuevo del que APT está dispuesto a instalar, y cree que libssl3 no es instalable bajo la configuración actual de repos/pins.

Decisión: No fuerces una instalación. Determina qué repo ofrece qué versiones de libc6 y libssl3, y si estás atascado en un libc más antiguo debido a retenciones/pins o a una actualización parcial.

Tarea 6: Comprueba si hay paquetes retenidos (clásico pie-pistola)

cr0x@server:~$ apt-mark showhold
libc6
linux-image-amd64

Significado: Tener libc6 retenido es un gran problema. Retener libc6 puede congelar el sistema porque todo depende de él directa o indirectamente.

Decisión: Si la retención fue intencional para una ventana de cambios, programa la ventana y quita la retención. Si fue accidental (o heredada de una imagen base), quita la retención ahora.

Tarea 7: Quitar la retención de paquetes (solo tras entender por qué fueron retenidos)

cr0x@server:~$ sudo apt-mark unhold libc6 linux-image-amd64
Canceled hold on libc6.
Canceled hold on linux-image-amd64.

Significado: APT ahora puede actualizar esos paquetes.

Decisión: Reejecuta el cálculo de dependencias. Si este era el único bloqueador, tus “dependencias incumplidas” pueden desaparecer.

Tarea 8: Busca pinning y preferencias que fuerzan elecciones extrañas

cr0x@server:~$ grep -R --line-number --no-messages '' /etc/apt/preferences /etc/apt/preferences.d 2>/dev/null
/etc/apt/preferences.d/00-local-pin:1:Package: *
/etc/apt/preferences.d/00-local-pin:2:Pin: release a=bookworm
/etc/apt/preferences.d/00-local-pin:3:Pin-Priority: 990

Significado: Alguien puso un pin para todo el sistema hacia bookworm. En Debian 13, eso es básicamente decirle a APT que prefiera paquetes de Debian 12. Así se crea un Debian Frankenstein.

Decisión: Elimina o ajusta el pin. Si necesitas pinning, pinnea solo los paquetes específicos que requieres, no Package: *.

Broma #1: Pinar Package: * es como arreglar una puerta chirriante moviendo toda la casa dos pulgadas a la izquierda.

Tarea 9: Comprueba versiones candidatas de los paquetes conflictivos

cr0x@server:~$ apt-cache policy libc6 libssl3 vendor-agent
libc6:
  Installed: 2.36-9
  Candidate: 2.39-5
  Version table:
     2.39-5 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages
 *** 2.36-9 100
        100 /var/lib/dpkg/status
libssl3:
  Installed: (none)
  Candidate: 3.3.1-1
  Version table:
     3.3.1-1 500
        500 http://deb.debian.org/debian trixie/main amd64 Packages
vendor-agent:
  Installed: (none)
  Candidate: 1.8.2-4
  Version table:
     1.8.2-4 500
        500 http://packages.vendor.example/debian bookworm/main amd64 Packages

Significado: Debian 13 ofrece libc6 y libssl3 más recientes. El agente del proveedor viene de un repo de Debian 12, pero sus dependencias podrían ser satisfechas si APT no está pinneado/retenido en versiones antiguas.

Decisión: Arregla primero la suite del repo del proveedor (o deshabilítalo). Luego realiza una actualización completa controlada para que libc6 pueda transicionar limpiamente.

Tarea 10: Deshabilita temporalmente un repo de terceros que no coincide

cr0x@server:~$ sudo mv /etc/apt/sources.list.d/vendor.list /etc/apt/sources.list.d/vendor.list.disabled
cr0x@server:~$ sudo apt update
Hit:1 http://deb.debian.org/debian trixie InRelease
Hit:2 http://deb.debian.org/debian trixie-updates InRelease
Hit:3 http://security.debian.org/debian-security trixie-security InRelease
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done

Significado: Eliminaste el universo de paquetes incompatible de la consideración. Eso a menudo resuelve los errores de “situación imposible”.

Decisión: Ahora alinea tus paquetes instalados con Debian 13 realizando una actualización completa. Más tarde, vuelve a habilitar el repo del proveedor solo si tiene una suite Debian 13.

Tarea 11: Comprueba dpkg por paquetes medio configurados/medio instalados

cr0x@server:~$ dpkg -C
The following packages are only half configured, probably due to problems
configuring them the first time. The configuration should be retried using
dpkg --configure <package> or the configure menu option in dselect:
 systemd 252.22-1  system and service manager

Significado: dpkg informa un estado inconsistente. Incluso si APT puede calcular un plan, puede fallar hasta que dpkg termine la configuración.

Decisión: Repara el estado de dpkg antes de intentar upgrades mayores.

Tarea 12: Configura los paquetes pendientes

cr0x@server:~$ sudo dpkg --configure -a
Setting up systemd (252.22-1) ...
Created symlink /etc/systemd/system/multi-user.target.wants/cron.service → /lib/systemd/system/cron.service.
Processing triggers for dbus (1.14.10-1) ...
Processing triggers for libc-bin (2.36-9) ...

Significado: dpkg completó la configuración pendiente y ejecutó triggers. Esto es fundamental.

Decisión: Reejecuta el paso de planificación de upgrades. Si dpkg da error aquí, detente y arregla ese error específicamente (a menudo un script de mantenedor roto o un archivo faltante).

Tarea 13: Deja que APT corrija dependencias faltantes (con los ojos abiertos)

cr0x@server:~$ sudo apt-get -f install
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Correcting dependencies... Done
The following additional packages will be installed:
  libpam-systemd systemd-sysv
The following packages will be upgraded:
  libpam-systemd systemd-sysv
2 upgraded, 0 newly installed, 0 to remove and 17 not upgraded.
Need to get 1,214 kB of archives.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n] y
...

Significado: APT encontró un conjunto mínimo de upgrades para restaurar la consistencia. Observa que no propuso eliminaciones. Buena señal.

Decisión: Acepta si los cambios son razonables. Si propone eliminar servicios críticos, detente y reconsidera la alineación de repos y pins.

Tarea 14: Ejecuta una actualización completa para permitir transiciones

cr0x@server:~$ sudo apt full-upgrade
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
The following packages will be upgraded:
  base-files libc6 libc-bin libssl3 openssh-client openssh-server
The following packages will be installed:
  linux-image-6.12.0-1-amd64 linux-headers-6.12.0-1-amd64
The following packages will be removed:
  linux-image-6.1.0-18-amd64
8 upgraded, 2 newly installed, 1 to remove and 0 not upgraded.
Need to get 76.4 MB of archives.
After this operation, 312 MB of additional disk space will be used.
Do you want to continue? [Y/n] y
...

Significado: Esta es una transición normal de kernel: instalar kernel nuevo, eliminar el antiguo. libc6 y libssl3 se actualizan coherentemente con Debian 13.

Decisión: Procede. Si estás en remoto, asegúrate de no dejar SSH inutilizable: mantén una sesión activa, considera una segunda sesión y no cortes la red durante el upgrade.

Tarea 15: Si APT aún no resuelve, pídele que explique por qué

cr0x@server:~$ apt -o Debug::pkgProblemResolver=yes install vendor-agent
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Starting pkgProblemResolver with broken count: 0
Investigating (0) vendor-agent:amd64 < none -> 1.8.2-4 @un puN Ib >
Broken vendor-agent:amd64 Depends on libc6:amd64 >= 2.37
  Considering libc6:amd64 100 as a solution to vendor-agent:amd64 9999
  Rejected libc6:amd64 100 because of held packages or policy
E: Unable to correct problems, you have held broken packages.

Significado: La salida de depuración muestra rechazo debido a “policy” (pins/preferencias) o retenciones. Ahora sabes dónde mirar: apt-mark showhold y /etc/apt/preferences*.

Decisión: Elimina la restricción de política y vuelve a intentarlo. No instales aleatoriamente versiones antiguas para apaciguar al resolvedor.

Tarea 16: Inspecciona la cadena de dependencias de un paquete específico

cr0x@server:~$ apt-cache depends vendor-agent | sed -n '1,80p'
vendor-agent
  Depends: libc6
  Depends: libssl3
  Depends: systemd
  Depends: adduser
  Depends: ca-certificates

Significado: Esto no es exótico; es un agente típico que depende de librerías centrales y systemd.

Decisión: Si las librerías centrales están bloqueadas, arregla esas librerías primero. No trates al agente como el problema; trátalo como el mensajero.

Tarea 17: Limpia paquetes y caches obsoletas (después de la recuperación)

cr0x@server:~$ sudo apt autoremove --purge
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  linux-image-6.1.0-18-amd64*
0 upgraded, 0 newly installed, 1 to remove and 0 not upgraded.
After this operation, 287 MB disk space will be freed.
Do you want to continue? [Y/n] y
...

Significado: Estás limpiando kernels antiguos u dependencias huérfanas. Esto no arregla problemas de dependencias; reduce el desorden después de resolverlos.

Decisión: Seguro después de confirmar que tienes un kernel nuevo arrancable. En servidores, conserva al menos un kernel conocido como bueno hasta después de reiniciar.

Tarea 18: Verifica la salud del sistema después del upgrade

cr0x@server:~$ sudo systemctl is-system-running
running

Significado: systemd considera el sistema sano. Si devuelve degraded, comprueba las unidades fallidas.

Decisión: Si está degradado, ejecuta systemctl --failed, arregla problemas de servicio y luego reinicia en tu ventana (las actualizaciones de kernel/libc suelen requerirlo).

Broma #2: “Dependencias incumplidas” es la forma que tiene APT de decir: “Puedo hacer cualquier cosa… excepto estar de acuerdo con tu yo del pasado.”

Tres micro-historias del mundo corporativo (por qué pasa esto en entornos serios)

Incidente #1: La suposición equivocada (“Es solo una línea de repo”)

Tuvieron una flota de servidores Debian construidos a partir de una imagen dorada que vivió años. La imagen era “mayormente estable”, que en lenguaje corporativo significa que nadie quería ser quien la tocara. Se necesitó un nuevo agente de observabilidad para una auditoría y el proveedor proporcionó un fragmento de repo. Alguien lo añadió, ejecutó apt update y luego instaló el agente. Funcionó. En un equipo.

Dos semanas después, un trabajo automático de seguridad ejecutó apt upgrade en la flota. APT empezó a tirar de una librería más nueva del repo del proveedor en algunos hosts—solo en aquellos que tenían instalado cierto paquete opcional. Esos equipos quedaron con una actualización parcial: un par de librerías avanzaron, pero paquetes centrales se quedaron atrás debido a retenciones que se introdujeron años antes para congelar kernels durante una mala época de drivers.

El síntoma fue clásico: “Depends: libc6 (>= …) but … is to be installed.” SSH todavía funcionaba, pero el agente de auditoría no se instaló en la mitad de la flota y el informe de cumplimiento los marcó como faltantes. Así es como “dependencias incumplidas” se convierte en un problema de negocio.

La suposición equivocada: que una sola línea de repo del proveedor es “local” al paquete del proveedor. No lo era. Los repos no están scopeados. El momento en que añades un repo añades un universo entero de paquetes que APT puede considerar para upgrades a menos que lo pinnees.

La solución fue aburrida y correcta: deshabilitar el repo del proveedor por defecto y luego añadir un pin que permitiera solo los paquetes del agente (y sus dependencias exactas) desde ese origen. El resto se quedó puro Debian. También quitaron las retenciones de libc6 después de una ventana de reboot planificada. El incidente terminó no con heroísmos, sino con un archivo de políticas y una checklist.

Incidente #2: Una optimización que salió mal (“Cacheemos paquetes en un espejo local”)

Otra compañía intentó ser lista. Montaron un proxy APT local para reducir ancho de banda externo y acelerar el aprovisionamiento. Buena idea. Luego “optimizaron” aún más al espejar solo un subconjunto de repositorios: main, sin security y solo amd64. El razonamiento fue: “Solo instalamos desde main, y security viene después.” Security, famosamente, no viene después.

Durante una ola de upgrades rutinaria, algunas máquinas apuntaban al mirror local y otras a los mirrors públicos de Debian. Un puñado de paquetes tenía versiones más nuevas en security y updates, y esas versiones requerían transiciones de librerías que no estaban presentes en el mirror truncado. El resultado fue un mundo de paquetes dividido: nombres de host idénticos en distintos racks, pero con versiones candidatas diferentes. La resolución de dependencias falló en los hosts apuntando al mirror local.

El equipo intentó “arreglarlo” forzando paquetes individuales con apt install package=version. Eso funcionó hasta que dejó de hacerlo: las versiones pinneadas derivaron y el siguiente ciclo de upgrades reintrodujo conflictos. La optimización creó una nueva clase de outages: el mirror en sí mismo se volvió una fuente de verdad poco fiable.

La reparación final fue: espejar el conjunto completo de suites usadas en producción (incluyendo security), mantener metadatos consistentes y forzar la configuración de repos vía gestión de configuración. El coste fue más disco. El beneficio: las actualizaciones dejaron de ser una moneda al aire.

Incidente #3: La práctica aburrida que salvó el día (“Hacemos snapshot antes de upgrades”)

Un entorno con mucho almacenamiento (nodos de procesamiento de datos) ejecutaba Debian con ZFS-on-root. Tenían una regla: antes de cualquier actualización del SO, tomar un snapshot del entorno de arranque. No era glamoroso. Era una línea en su runbook y un hook pre-upgrade en su automatización.

Una noche sucedió una actualización parcial de todos modos: un corte de red durante las descargas de paquetes. dpkg terminó con un paquete central desempaquetado pero sin configurar. Los errores de APT se propagaron. El nodo seguía accesible, pero los servicios quedaban atascados al reiniciarse y la persona on-call manejaba múltiples alertas.

En lugar de improvisar, siguieron el camino aburrido. Usaron dpkg para configurar paquetes pendientes, ejecutaron apt-get -f install y reintentaron la actualización completa. Cuando un script de mantenedor falló por una personalización local, no lo parcharon en el sitio; hicieron rollback al snapshot, corrigieron la personalización y volvieron a ejecutar la actualización.

No fue dramático, que es el punto. El snapshot convirtió “dependencias incumplidas” de “tal vez reconstruir el nodo” a “reparación repetible”. Aun así arreglaron el problema subyacente, pero sin pánico.

Errores comunes: síntoma → causa raíz → arreglo

1) Síntoma: “Depends: X but it is not installable” justo después de añadir un repo de proveedor

Causa raíz: El repo apunta a una release diferente (o Ubuntu), o te faltan componentes requeridos (como contrib, non-free-firmware) para tus necesidades.

Arreglo: Deshabilita el repo; confirma la suite/nombre en clave correcto; vuelve a habilitar solo si coincide con Debian 13. Si debes mantenerlo, pinnea a paquetes específicos, no a todo el universo.

2) Síntoma: “You have held broken packages”

Causa raíz: Retenciones explícitas vía apt-mark hold, o pins que efectivamente retienen una versión.

Arreglo: apt-mark showhold, luego quita la retención de forma intencional. Inspecciona /etc/apt/preferences* por pins generales.

3) Síntoma: APT sugiere eliminar la mitad de tu escritorio / tu servidor SSH

Causa raíz: Suites mixtas (stable + testing + unstable), o un repo de terceros que reemplaza paquetes centrales, o una mezcla de arquitecturas accidental.

Arreglo: Haz que las fuentes sean consistentes. Si quieres Debian 13 stable, usa solo suites de Debian 13 (más backports si están configurados intencionalmente). Elimina paquetes de arquitecturas foráneas si fueron añadidos por accidente.

4) Síntoma: “dpkg fue interrumpido, debes ejecutar dpkg –configure -a”

Causa raíz: Instalación/upgrade interrumpido, reinicio abrupto, proceso apt matado o un hang en un script de mantenedor.

Arreglo: Ejecuta sudo dpkg --configure -a. Si falla, lee el error exacto, arregla el archivo/servicio que menciona y vuelve a ejecutar. No sigas intentando sin cambiar nada.

5) Síntoma: “E: Could not get lock /var/lib/dpkg/lock-frontend”

Causa raíz: Otro proceso apt/dpkg está en ejecución (o uno se estrelló y dejó confusión).

Arreglo: Identifica el proceso con ps, espera si es legítimo, o deténlo si está atascado. No borres archivos lock como primer movimiento; así es como se corrompe el estado.

6) Síntoma: “Packages have been kept back” para componentes centrales

Causa raíz: La actualización requiere instalar paquetes nuevos/eliminar antiguos; el upgrade conservador de APT no lo hará.

Arreglo: Usa apt full-upgrade y revisa el plan. Si el plan es absurdo, tus fuentes/pins aún están mal.

7) Síntoma: transiciones de libc6 u openssl fallan

Causa raíz: Falta un repo (security/updates), paquetes de terceros requieren versiones de otra suite, o tienes pinneado libc/openssl antiguos.

Arreglo: Asegura que los repos de Debian estén completos y alineados, elimina retenciones/pins, elimina temporalmente el paquete de terceros si hace falta, completa la transición del SO base y luego vuelve a añadir los paquetes de terceros.

8) Síntoma: “The following signatures were invalid” y luego la actualización falla más tarde

Causa raíz: Dejas de recibir actualizaciones, por lo que tu sistema derivó. Más tarde intentas instalar algo que asume dependencias más nuevas.

Arreglo: Arregla primero la firma/las claves del repo, ejecuta apt update y luego haz un full-upgrade para resincornizar.

Listas de verificación / plan paso a paso

Checklist A: Devolver APT a la consistencia (la base segura)

  1. Confirma la release: /etc/os-release debe coincidir con el nombre en clave de Debian 13.
  2. Inspecciona fuentes: elimina/deshabilita suites que no coincidan y repos de terceros aleatorios.
  3. Ejecuta apt update y asegúrate de que termine sin errores de repos.
  4. Revisa retenciones: apt-mark showhold; quita retenciones de paquetes centrales a menos que tengas una razón documentada.
  5. Revisa pinning: inspecciona /etc/apt/preferences* por pins amplios; elimínalos o limítalos.
  6. Arregla el estado de dpkg: dpkg -C, luego dpkg --configure -a.
  7. Ejecuta apt-get -f install para reparar rupturas de dependencias.
  8. Ejecuta apt full-upgrade para completar las transiciones.
  9. Reinicia si cambió kernel/libc/systemd (usualmente sí). Luego verifica servicios.

Checklist B: Si debes mantener un repo de terceros

  1. Asegúrate de que el repo apunte a la suite Debian 13 (no Debian 12, ni Ubuntu).
  2. Prefiere limitar el alcance del repo mediante pinning:
    • Pinnea por origin y nombre de paquete, no globalmente.
    • Mantén los paquetes del proveedor con prioridad más baja a menos que se instalen explícitamente.
  3. Documenta la excepción: qué paquetes vienen del proveedor, por qué y cómo hacer rollback si desaparecen.
  4. Reprueba las actualizaciones en un entorno de staging que refleje exactamente las fuentes de producción.

Checklist C: Cuando ya estás en un lío de actualización parcial

  1. Detén la automatización de fondo (unattended-upgrades, tareas de gestión de configuración) hasta terminar la reparación.
  2. Repara la configuración de dpkg primero (dpkg --configure -a).
  3. Luego repara dependencias (apt-get -f install).
  4. Luego realiza la actualización completa (apt full-upgrade).
  5. Sólo después de que el SO base sea consistente, vuelve a habilitar repos de terceros y reinstala sus paquetes si es necesario.

Preguntas frecuentes

1) ¿Realmente necesito apt full-upgrade? Suena aterrador.

A veces, sí. Si una transición requiere instalar dependencias nuevas o eliminar paquetes obsoletos, apt upgrade se negará. full-upgrade no es imprudente; es honesto. Lee el plan antes de aceptar.

2) ¿Cuál es la diferencia entre APT y dpkg en este lío?

APT decide qué debe pasar; dpkg lo ejecuta. Si APT no puede encontrar una solución válida, eso es un problema de política/repos/versiones. Si dpkg no puede configurar paquetes, eso es una instalación interrumpida o un script/config roto.

3) ¿Está bien borrar archivos lock de dpkg?

Rara vez. Primero confirma que no hay un proceso apt/dpkg legítimo en ejecución. Borrar locks mientras dpkg está activo es una excelente manera de corromper el estado. Si lo estás considerando, probablemente necesites bajar el ritmo e inspeccionar procesos.

4) ¿Por qué APT dice que un paquete “no es instalable” cuando existe en el repo?

Porque “instalable” significa “instalable bajo las restricciones actuales”: suite, arquitectura, pins y versiones de dependencias. Un paquete puede existir pero estar excluido por pinning, suite equivocada o componentes faltantes.

5) ¿Puedo arreglar dependencias incumplidas descargando .deb aleatorios?

También puedes arreglar una tubería con chicle. Puede aguantar lo suficiente para arruinar tu fin de semana. Prefiere repositorios consistentes y deja que APT gestione versiones a menos que estés haciendo una reparación puntual y muy controlada.

6) ¿Cómo sé si tengo releases Debian mezcladas?

apt-cache policy muestra las líneas de release. Si ves múltiples suites (como trixie más bookworm o sid) con prioridades similares, estás mezclando. También inspecciona /etc/apt/sources.list* en busca de nombres de suite.

7) ¿Y si la única forma de satisfacer dependencias es eliminar un servicio clave?

Eso suele indicar que tus repositorios están mal o te has pinneado hasta un rincón. Arregla primero fuentes y pins. Si es un paquete de terceros el que causa conflicto, elimínalo temporalmente, completa el upgrade del SO y luego reinstala el paquete de terceros desde un repo compatible.

8) ¿Debería usar aptitude en su lugar?

Puede ofrecer soluciones alternativas de forma interactiva, lo cual es útil cuando entiendes el sistema. No sustituye a repos/pins correctos. Si tus fuentes están mal, aptitude aún te presentará malas opciones—solo de forma más creativa.

9) ¿Por qué esto ocurre más durante actualizaciones de Debian que en “días normales”?

Las transiciones de release y los updates puntuales desencadenan cambios coordinados: libc, openssl, systemd, kernels. Si tienes retenciones, pins o suites faltantes (como security), esas transiciones fallan ruidosamente.

10) ¿Cuándo está justificada la reinstalación?

Cuando tienes ediciones manuales no rastreadas, repos de terceros desconocidos y años de deriva—más sin snapshots y sin tiempo para razonar. Reinstalar es una decisión operacional, no un requisito técnico. La mayoría de las veces puedes reparar más rápido de lo que puedes reconstruir con seguridad.

Conclusión: pasos siguientes que deberías hacer

Si APT te grita sobre dependencias incumplidas en Debian 13, trátalo como un problema de consistencia, no de voluntad.

  1. Haz que las fuentes sean coherentes. Una release de Debian, suites completas (main + updates + security) y sin repos de terceros desajustados.
  2. Elimina trampas de política. Quita retenciones de paquetes centrales, deshaz pins amplios y deja de mezclar releases a menos que lo hagas deliberadamente con restricciones estrictas.
  3. Repara el estado de dpkg. dpkg -C luego dpkg --configure -a antes de intentar grandes actualizaciones.
  4. Deja que APT complete las transiciones. Usa apt-get -f install para restaurar la consistencia y luego apt full-upgrade para terminar el trabajo.
  5. Después, fija la corrección aburrida. Gestiona por configuración tus archivos de repos, documenta repos de terceros y haz snapshots antes de upgrades si puedes.

El objetivo no es “hacer que el error desaparezca”. El objetivo es restaurar un sistema donde cada versión de paquete tenga un origen claro y una vía de actualización que no requiera rezos.

← Anterior
WordPress 502 Bad Gateway: PHP-FPM, Nginx, Cloudflare — Cómo encontrar al culpable
Siguiente →
Caché de WordPress que no rompe carritos ni formularios

Deja un comentario