Ubuntu 24.04: «No se pudo obtener la conexión D-Bus» — arreglar sesiones y servicios rotos (caso #48)

¿Te fue útil?

Ejecutas systemctl y aparece: «No se pudo obtener la conexión D-Bus». De pronto tu “reinicio simple” se convierte en una escena del crimen: los servicios no se comunican, los inicios de sesión parecen embrujados y toda automatización que espera una sesión limpia empieza a fallar.

Este error rara vez es “solo D-Bus”. Suele ser un contrato roto entre systemd, tu sesión/inicio de sesión y los sockets del bus bajo /run. La solución es aburrida—pero solo después de que dejes de adivinar y empieces a probar.

Qué significa realmente el error (y qué no significa)

Cuando una herramienta dice «No se pudo obtener la conexión D-Bus», se queja de que no puede alcanzar un socket de bus de mensajes que espera que exista. En Ubuntu 24.04, los llamantes habituales son systemctl, loginctl, componentes de GNOME, avisos de policykit, asistentes de snapd, o cualquier proceso que espere ya sea:

  • El bus del sistema en /run/dbus/system_bus_socket (usado para servicios a nivel del sistema), o
  • El bus de la sesión de usuario (por usuario) típicamente en /run/user/UID/bus, gestionado por systemd --user y dbus-daemon o dbus-broker según la configuración.

La frase es engañosa porque la causa raíz a menudo no es “D-Bus está caído”. El bus puede estar bien; tu entorno puede ser incorrecto, tu directorio runtime puede no existir, podrías estar dentro de un contenedor/namespace, o podrías estar usando sudo de una manera que elimina las variables del bus.

Dos reglas que te mantienen cuerdo:

  1. Decide si necesitas el bus del sistema o el bus de usuario. Si administras servicios con systemctl (ámbito del sistema), te importa PID 1, dbus y el socket del sistema. Si ejecutas acciones de escritorio/sesión, te importan systemd --user, XDG_RUNTIME_DIR y el socket por usuario.
  2. Siempre prueba el socket, no tus corazonadas. La mayoría de las caídas de “conexión D-Bus” son en realidad rutas faltantes bajo /run, sesiones de usuario muertas o un gestor de inicio de sesión roto.

Una idea parafraseada de Gene Kim (autor sobre DevOps/fiabilidad): La mejora viene de reducir el trabajo en curso y hacer visibles los problemas temprano. Eso aplica aquí: haz visible la falla comprobando primero las rutas del bus y el estado de la sesión, no reiniciando demonios al azar.

Guion de diagnóstico rápido

Cuando esto ocurre en producción a las 02:00, no quieres teoría. Quieres un bucle de triaje que converja.

Paso 1: Identificar qué bus falla

  • Si el error aparece al ejecutar systemctl status foo como root, probablemente sea el bus del sistema o la conectividad con PID 1.
  • Si el error aparece en una app de escritorio, ajustes de GNOME, o systemctl --user, es el bus de la sesión de usuario (/run/user/UID/bus).
  • Si solo sucede por SSH o automatización, sospecha de variables de entorno y shells no interactivos.

Paso 2: Comprobar sockets y directorios runtime (señal más rápida)

  • ¿Existe /run/dbus/system_bus_socket y es un socket?
  • ¿Existe /run/user/UID y es propiedad del usuario?
  • ¿Existe /run/user/UID/bus y es un socket?

Paso 3: Validar el gestor de sesión y el estado de systemd

  • systemctl is-system-running te dice si PID 1 está saludable.
  • systemctl status dbus te indica si el servicio del bus del sistema existe/arrancó.
  • loginctl list-sessions te dice si logind ve tu sesión (crítico para la creación de /run/user/UID).

Paso 4: Arregla la capa correcta, no la más ruidosa

  • ¿Falta /run/user/UID? Arregla el ciclo de vida de logind/sesión.
  • ¿El socket existe pero acceso denegado? Arregla permisos, políticas SELinux/AppArmor o el contexto del usuario.
  • ¿Funciona localmente pero no con sudo? Arregla la preservación del entorno; no “reinicies dbus” por despecho.

Datos interesantes y contexto (depurarás más rápido)

  • D-Bus fue diseñado a principios de los 2000 para reemplazar mecanismos ad-hoc de IPC en escritorios Linux; más tarde se volvió estándar también para servicios del sistema.
  • systemd no creó D-Bus, pero systemd hizo más explícitos los patrones de dependencia de D-Bus con ordenación de unidades, activación por socket y servicios de usuario.
  • Los directorios runtime de usuario bajo /run/user/UID suelen ser creados por systemd-logind cuando se inicia una sesión—y se eliminan cuando termina la última sesión.
  • Ubuntu ha incluido tanto dbus-daemon como alternativas (como dbus-broker en algunos entornos); lo que importa es el contrato del socket, no la marca de implementación.
  • XDG_RUNTIME_DIR es parte de la especificación XDG; debe ser específico del usuario, seguro y efímero—exactamente lo opuesto a un directorio aleatorio bajo /tmp.
  • systemctl habla con systemd sobre D-Bus; si systemctl no puede alcanzar un bus, no puede pedirle nada a systemd, incluso si systemd está técnicamente vivo.
  • Las sesiones SSH no siempre son “sesiones logind” dependiendo de la configuración de PAM; cuando no lo son, puedes perder la creación automática del directorio runtime y la disponibilidad del bus de usuario.
  • Los contenedores a menudo no tienen un bus del sistema completo porque PID 1 no es systemd, o porque /run está aislado. Este error es normal allí a menos que lo conectes deliberadamente.
  • PolicyKit (polkit) depende de D-Bus para consultas de autorización; el acceso roto al bus puede parecer “los avisos de autenticación no aparecen” o “permiso denegado” sin interfaz gráfica.

Broma #1: D-Bus es como el correo de oficina—cuando falla, todos de repente descubren cuántas cosas dependían de él sin haberlo sabido.

Guía de campo: aislar qué “bus” no alcanzas

Hay algunas formas comunes de fallo:

  • Root en un servidor: systemctl falla. Por lo general el socket del bus del sistema falta, la unidad dbus falló, o PID 1 está en un estado degradado/medio muerto.
  • Sesión de usuario de escritorio: fallan ajustes de GNOME, gsettings se rompe, systemctl --user falla. Suelen faltar XDG_RUNTIME_DIR, /run/user/UID o systemd --user no está en ejecución.
  • Automatización vía sudo: funciona como tu usuario, falla como root, o al revés. Normalmente las variables de entorno y el contexto de sesión son incorrectos.
  • Dentro de contenedores/CI: systemctl y busctl fallan por diseño porque no hay systemd PID 1 ni bus del sistema.

Clave: el bus es un archivo de socket Unix. Si el socket no está, no vas a “reintentar con más fuerza.” Si está pero tu proceso no puede acceder, tratas problemas de permisos, namespaces o identidad. Si está y es accesible pero las respuestas fallan, entonces hay un problema del demonio.

Tareas prácticas: comandos, salida esperada y decisiones

Estas son las tareas que realmente ejecuto. Cada una incluye qué significa la salida y qué decisión tomar a continuación. Ejecútalas en orden hasta que el modo de fallo sea obvio. No colecciones registros por diversión; estás reduciendo el espacio de búsqueda.

Task 1: Confirmar el comando que falla y el contexto exacto

cr0x@server:~$ whoami
cr0x
cr0x@server:~$ systemctl status ssh
Failed to get D-Bus connection: No such file or directory

Significado: El cliente no puede alcanzar su socket del bus. “No such file or directory” sugiere una ruta de socket faltante, no un problema de permisos.

Decisión: Determina si es una falla del bus del sistema (ámbito root/sistema) o del bus de usuario (ámbito usuario). Siguiente: comprueba si eres root y qué systemctl ejecutaste.

Task 2: Comprobar si PID 1 es systemd (contenedores y chroots)

cr0x@server:~$ ps -p 1 -o pid,comm,args
  PID COMMAND         COMMAND
    1 systemd         /sbin/init

Significado: PID 1 es systemd; systemctl debería funcionar si la ruta del bus del sistema está presente.

Decisión: Si PID 1 no es systemd (común en contenedores), la “solución” es evitar systemctl o ejecutar un init apropiado. Si es systemd, continúa.

Task 3: Verificar que exista el socket del bus del sistema

cr0x@server:~$ ls -l /run/dbus/system_bus_socket
srwxrwxrwx 1 root root 0 Dec 30 10:12 /run/dbus/system_bus_socket

Significado: El archivo socket del bus del sistema existe y es un socket (la primera letra s en permisos). Que sea escribible por todos es normal para el endpoint; el acceso se controla aún por la política de D-Bus.

Decisión: Si falta: enfócate en el servicio dbus y en problemas de arranque temprano. Si está presente: prueba si dbus responde.

Task 4: Comprobar la salud del servicio dbus (bus del sistema)

cr0x@server:~$ systemctl status dbus --no-pager
● dbus.service - D-Bus System Message Bus
     Loaded: loaded (/usr/lib/systemd/system/dbus.service; static)
     Active: active (running) since Mon 2025-12-30 10:12:01 UTC; 2min ago
TriggeredBy: ● dbus.socket
       Docs: man:dbus-daemon(1)
   Main PID: 842 (dbus-daemon)
      Tasks: 1 (limit: 18939)
     Memory: 3.8M
        CPU: 52ms

Significado: El bus del sistema está en ejecución; el problema puede ser la capacidad de systemctl para conectarse a systemd (no a dbus), o un problema de namespace/permiso.

Decisión: Si dbus está inactivo/falló, reinícialo y lee los registros. Si está activo, comprueba systemd mismo y el socket privado de systemd.

Task 5: Confirmar que systemd responde

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

Significado: PID 1 informa que está saludable. Si aún ves “Failed to get D-Bus connection”, puede que estés ejecutando systemctl en un entorno que no ve /run o que carece del namespace de montaje correcto.

Decisión: Si la salida es degraded o maintenance, ve directamente al journal por fallos sistémicos. Si es running pero los clientes fallan, sospecha de namespaces, chroot o problemas del sistema de archivos bajo /run.

Task 6: Inspeccionar el montaje de /run y el espacio libre (sí, en serio)

cr0x@server:~$ findmnt /run
TARGET SOURCE FSTYPE OPTIONS
/run   tmpfs  tmpfs  rw,nosuid,nodev,relatime,size=394680k,mode=755,inode64
cr0x@server:~$ df -h /run
Filesystem      Size  Used Avail Use% Mounted on
tmpfs           386M  2.1M  384M   1% /run

Significado: /run es tmpfs; debe ser escribible y tener espacio/inodos. Si /run está en solo lectura o lleno, no se crearán sockets y obtendrás errores de bus faltante.

Decisión: Si está lleno/ro: arregla eso primero (a menudo un proceso descontrolado o un tamaño de tmpfs mal configurado). Si está sano: continúa con las comprobaciones de sesión de usuario si el error es de ámbito usuario.

Task 7: Determinar si tratas con el bus de usuario

cr0x@server:~$ echo "$XDG_RUNTIME_DIR"
/run/user/1000
cr0x@server:~$ echo "$DBUS_SESSION_BUS_ADDRESS"
unix:path=/run/user/1000/bus

Significado: Las variables de entorno apuntan al bus por usuario. Si alguna está vacía, tu sesión está incompleta (común con sudo, cron o PAM roto).

Decisión: Si están sin establecer: debes establecer un contexto de sesión correcto o configurar explícitamente un bus de usuario (prefiere lo primero). Si están establecidas: comprueba que el socket exista.

Task 8: Validar que el socket del bus de usuario exista y tenga propiedad sensata

cr0x@server:~$ id -u
1000
cr0x@server:~$ ls -ld /run/user/1000
drwx------ 12 cr0x cr0x 320 Dec 30 10:12 /run/user/1000
cr0x@server:~$ ls -l /run/user/1000/bus
srw-rw-rw- 1 cr0x cr0x 0 Dec 30 10:12 /run/user/1000/bus

Significado: El directorio runtime existe, es privado (0700) y el socket del bus existe. Bien. Si /run/user/1000 falta, tu sesión no se registró correctamente con logind.

Decisión: Si falta: salta a la resolución de loginctl y PAM/logind. Si está presente pero con propietario incorrecto: corrige la propiedad e investiga por qué se desvió (a menudo un script mal ejecutado como root).

Task 9: Demostrar que la instancia de systemd del usuario está viva

cr0x@server:~$ systemctl --user status --no-pager
● cr0x@server
    State: running
    Units: 221 loaded (incl. snap units)
     Jobs: 0 queued
   Failed: 0 units
    Since: Mon 2025-12-30 10:12:05 UTC; 2min ago
  

Significado: Tu gestor de usuario está en ejecución y accesible. Si obtienes “Failed to connect to bus”, la ruta del bus de usuario o el entorno están rotos.

Decisión: Si esto falla pero el socket existe, tu entorno puede estar mintiendo (XDG_RUNTIME_DIR incorrecto) o estás en un namespace distinto (común con sudo y algunas herramientas remotas).

Task 10: Usar loginctl para verificar que logind vea tu sesión

cr0x@server:~$ loginctl list-sessions
SESSION  UID USER SEAT  TTY
     21 1000 cr0x seat0 tty2

1 sessions listed.
cr0x@server:~$ loginctl show-user cr0x -p RuntimePath -p State -p Linger
RuntimePath=/run/user/1000
State=active
Linger=no

Significado: logind tiene una sesión activa para el usuario y sabe dónde está la ruta runtime. Si no hay sesiones, tu directorio runtime de usuario puede no crearse.

Decisión: Si la sesión falta por SSH: revisa la configuración de PAM y si tu ruta de inicio usa systemd/logind. Si necesitas servicios de usuario en segundo plano, considera lingering (con cuidado).

Task 11: Diagnosticar “sudo rompió mi bus” (clásico)

cr0x@server:~$ sudo -i
root@server:~# echo "$DBUS_SESSION_BUS_ADDRESS"

root@server:~# systemctl --user status
Failed to connect to bus: No medium found

Significado: La shell de root no tiene contexto del bus de usuario; systemctl --user bajo root no es tu sesión de usuario. Ese error es esperado.

Decisión: No “arregles” esto exportando variables aleatorias a root. Usa systemctl (ámbito del sistema) como root, y systemctl --user como el usuario dentro de la sesión. Si debes gestionar una unidad de usuario desde root, usa machinectl shell o runuser con el entorno adecuado, o apunta al gestor de usuario vía loginctl enable-linger y systemctl --user bajo ese usuario.

Task 12: Revisar el journal por la primera falla, no por la última quejarse

cr0x@server:~$ journalctl -b -u systemd-logind --no-pager | tail -n 20
Dec 30 10:11:58 server systemd-logind[701]: New session 21 of user cr0x.
Dec 30 10:11:58 server systemd-logind[701]: Watching system buttons on /dev/input/event3 (Power Button)
Dec 30 10:12:01 server systemd-logind[701]: Removed session 19.

Significado: logind está creando sesiones. Si en su lugar ves fallos repetidos al crear directorios runtime, ese es tu arma humeante.

Decisión: Si logind muestra errores sobre directorios runtime o cgroups, arregla esas capas. Reiniciar dbus no arreglará “no se puede crear /run/user/UID”.

Task 13: Confirmar que los paquetes dbus y el soporte de sesión de usuario estén instalados

cr0x@server:~$ dpkg -l | egrep 'dbus|dbus-user-session|libpam-systemd' | awk '{print $1,$2,$3}'
ii dbus 1.14.10-4ubuntu4.1
ii dbus-user-session 1.14.10-4ubuntu4.1
ii libpam-systemd 255.4-1ubuntu8

Significado: Los componentes requeridos existen. La ausencia de dbus-user-session puede llevar a comportamientos de bus de sesión faltantes en algunas instalaciones mínimas.

Decisión: Si faltan: instala los paquetes y vuelve a iniciar sesión. Si están presentes: pasa a PAM/logind y problemas de entorno.

Task 14: Comprobar los hooks de sesión PAM para systemd/logind (enfocado en SSH)

cr0x@server:~$ grep -R "pam_systemd.so" -n /etc/pam.d/sshd /etc/pam.d/login
/etc/pam.d/sshd:15:session    required     pam_systemd.so
/etc/pam.d/login:14:session    required     pam_systemd.so

Significado: PAM está configurado para registrar sesiones con systemd/logind para SSH y consolas. Si falta, puedes quedarte sin directorio runtime y sin bus de usuario.

Decisión: Si está ausente para la vía de inicio que usas: añádelo (con cuidado, control de cambios) y prueba con una nueva sesión. Si está presente: céntrate en por qué logind aún no crea directorios runtime (a menudo relacionado con lingering, problemas de cgroups o estado de systemd roto).

Task 15: Comprobar si el directorio runtime del usuario se elimina inesperadamente

cr0x@server:~$ sudo ls -l /run/user
total 0
drwx------ 12 cr0x cr0x 320 Dec 30 10:12 1000
drwx------ 10 gdm  gdm  280 Dec 30 10:11 120

Significado: Existen directorios runtime para usuarios activos. Si el tuyo desaparece al desconectar SSH, probablemente no tienes lingering y no hay sesión activa.

Decisión: Para servicios de usuario en segundo plano: considera loginctl enable-linger username. Para trabajo interactivo: asegúrate de tener una sesión real y evita ejecutar comandos dependientes de la sesión desde contextos sin sesión.

Task 16: Habilitar lingering (solo si realmente necesitas servicios de usuario sin inicio de sesión)

cr0x@server:~$ sudo loginctl enable-linger cr0x
cr0x@server:~$ loginctl show-user cr0x -p Linger
Linger=yes

Significado: El gestor de usuario puede sobrevivir más allá de los inicios de sesión, manteniendo servicios de usuario y el directorio runtime disponible.

Decisión: Usa esto para servicios sin cabeza ejecutados en ámbito de usuario (a veces agentes CI, podman por usuario, etc.). No lo habilites en todas partes “por si acaso.” Así es como se obtienen gestores de usuario zombis consumiendo RAM en hosts compartidos.

Task 17: Si systemctl falla como root, prueba D-Bus directamente

cr0x@server:~$ busctl --system list | head
NAME                      PID PROCESS         USER CONNECTION UNIT SESSION DESCRIPTION
:1.0                      842 dbus-daemon     root :1.0       -    -       -
org.freedesktop.DBus      842 dbus-daemon     root :1.0       -    -       -
org.freedesktop.login1    701 systemd-logind  root :1.2       -    -       -

Significado: El bus del sistema responde. Si systemctl aún falla, podrías tener un endpoint D-Bus de systemd roto o un desajuste en el entorno/namespace.

Decisión: Si busctl también falla: el bus del sistema está genuinamente roto. Si busctl funciona: céntrate en la conectividad de systemd y el entorno del cliente.

Task 18: Comprobar el socket privado de systemd (endpoint IPC de systemd)

cr0x@server:~$ ls -l /run/systemd/private
srw------- 1 root root 0 Dec 30 10:11 /run/systemd/private

Significado: El socket privado de systemd existe; systemctl lo usa en algunos caminos de código. Si falta, algo está muy mal con PID 1 o /run.

Decisión: Si falta: trátalo como un problema de systemd/sistema de archivos runtime; considera un reinicio controlado después de extraer logs. Si está presente: vuelve al alcance (sistema vs usuario) y problemas de namespace.

Task 19: Detectar problemas de chroot/namespace (común en shells de recuperación)

cr0x@server:~$ readlink /proc/$$/ns/mnt
mnt:[4026532585]
cr0x@server:~$ sudo readlink /proc/1/ns/mnt
mnt:[4026531840]

Significado: Tu shell está en un namespace de montaje distinto al de PID 1. Puede que no veas el verdadero /run donde viven los sockets.

Decisión: Si los namespaces difieren, ejecuta diagnósticos desde el namespace del host (o entra en él) en lugar de “arreglar” rutas fantasma en tu vista aislada.

Task 20: Último recurso, reinicios controlados (en el orden correcto)

cr0x@server:~$ sudo systemctl restart systemd-logind
cr0x@server:~$ sudo systemctl restart dbus
cr0x@server:~$ sudo systemctl daemon-reexec

Significado: Estos reinicios pueden recuperar un logind/dbus/systemd bloqueado. daemon-reexec es pesado; re-ejecuta PID 1 sin reiniciar.

Decisión: Haz esto solo después de confirmar que no estás en un contenedor y de haber capturado suficientes logs para explicar el incidente. Si las sesiones de usuario están rotas por logind, reiniciar logind puede desconectar sesiones; prográmalo como si realmente importara.

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

1) «systemctl funciona como root localmente, falla por SSH»

Síntoma: Por SSH, systemctl devuelve “Failed to get D-Bus connection,” pero en la consola funciona.

Causa raíz: Estás en un entorno restringido (comando forzado, chroot, toolbox), o tu sesión SSH no ve /run del host (diferencia de namespace de montaje).

Arreglo: Confirma PID 1 y el namespace de montaje; asegúrate de que tu ruta SSH no esté chrooted y tenga acceso a /run. Usa Task 2 y Task 19.

2) «systemctl –user falla después de sudo -i»

Síntoma: Te conviertes en root e intentas gestionar servicios de usuario; falla con errores de bus.

Causa raíz: Root no tiene el entorno del bus de tu usuario. Además, el gestor de usuario de root no es el gestor de tu usuario.

Arreglo: Ejecuta systemctl --user como el usuario dentro de la sesión. Si debes hacerlo desde root, usa runuser -l username -c 'systemctl --user …' y asegúrate de una sesión adecuada (o habilita lingering).

3) «GNOME Settings no se abren; los avisos de polkit nunca aparecen»

Síntoma: Acciones de GUI fallan en silencio o se quejan de D-Bus.

Causa raíz: El bus de la sesión de usuario está roto: falta XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS está obsoleto, o falta /run/user/UID/bus.

Arreglo: Verifica Task 7/8. Cierra sesión y vuelve a entrar para recrear una sesión limpia. Si persiste, revisa logind e integración PAM.

4) «Trabajo cron falla con errores de D-Bus»

Síntoma: Un script que usa gsettings, notify-send o systemctl --user falla en cron.

Causa raíz: Cron se ejecuta sin una sesión de usuario y sin XDG_RUNTIME_DIR.

Arreglo: No ejecutes comandos de escritorio/sesión en cron a menos que crees un contexto de sesión. Usa servicios del sistema en su lugar, o habilita lingering y ejecuta un servicio de usuario que no dependa del estado de GUI.

5) «/run/user/UID existe pero es propiedad de root»

Síntoma: El directorio existe, pero los permisos son incorrectos; siguen errores del bus de usuario.

Causa raíz: Alguien ejecutó una “limpieza” como root y recreó directorios incorrectamente, o un script malicioso escribió en /run/user.

Arreglo: Cierra la sesión del usuario (termina sesiones), elimina el directorio runtime incorrecto y deja que logind lo recree. Si debes arreglar en caliente, corrige la propiedad y reinicia el gestor de usuario con cuidado.

6) «socket del bus del sistema faltante después del arranque»

Síntoma: /run/dbus/system_bus_socket está ausente; systemctl falla de forma amplia.

Causa raíz: dbus.socket o dbus.service no arrancó, o /run no se montó correctamente.

Arreglo: Valida el montaje de /run (Task 6), luego systemctl status dbus dbus.socket y revisa los logs del arranque temprano.

7) «Funciona en el host pero falla dentro de un contenedor»

Síntoma: systemctl y busctl fallan en una imagen de contenedor o runner CI.

Causa raíz: No hay systemd PID 1, no hay bus del sistema o /run está aislado.

Arreglo: No uses systemctl dentro de ese contenedor. Ejecuta el proceso del servicio en primer plano, o ejecuta un contenedor basado en systemd intencionalmente con los privilegios y montajes correctos.

Tres microhistorias corporativas desde el campo

Microhistoria #1: El incidente causado por una suposición equivocada

En una compañía mediana, un ingeniero on-call recibió una alerta de “host de despliegue no reinicia servicios.” Se conectó por SSH, ejecutó sudo systemctl restart app, y obtuvo “Failed to get D-Bus connection.” La suposición fue inmediata y segura: “dbus está caído; reinícialo.”

Reinició dbus. Luego logind. Luego intentó un daemon-reexec. El host se volvió más difícil de acceder y varias sesiones interactivas cayeron. La app seguía sin reiniciarse. El incidente se complicó.

El problema real fue mundano: el ingeniero no estaba en el host. Estaba en un chroot de mantenimiento que las herramientas de rescate del equipo usaban para trabajo de disco. Ese entorno tenía un namespace de montaje distinto y un /run distinto. Por supuesto que /run/dbus/system_bus_socket no existía allí; el socket del bus vivía en el namespace del host.

Una vez que salió del chroot y ejecutó el mismo comando en el entorno real del host, systemctl funcionó de inmediato. La “caída de D-Bus” fue un espejismo creado por el contexto. La solución fue añadir un banner claro en los entornos de rescate y enseñar al equipo a ejecutar Task 2 y Task 19 antes de tocar demonios.

Microhistoria #2: La optimización que salió mal

Otro equipo quiso tiempos de inicio más rápidos y menos procesos en segundo plano en estaciones de trabajo de desarrolladores. Alguien decidió “simplificar” quitando paquetes de la imagen base, incluidos componentes relacionados con la sesión que creían “fluff de escritorio”.

La imagen se distribuyó y fue rápida. Durante una semana. Luego llegaron los tickets: integraciones del IDE fallando, avisos de contraseña que no aparecían, toggles de configuración que no funcionaban, y uno curioso—servicios de usuario fallando solo después de reconectar por escritorio remoto.

Habían eliminado piezas que indirectamente garantizaban un bus de sesión de usuario estable. El bus del sistema aún existía, pero la infraestructura de sesión por usuario era inconsistente entre métodos de inicio. Algunos inicios creaban /run/user/UID correctamente; otros no, porque faltaban hooks de PAM y paquetes de sesión.

La optimización no fue “mala” por ahorrar CPU. Fue mala porque removió la andamiaje que hace predecible el bus de usuario. El rollback añadió los paquetes necesarios y estandarizó las rutas de inicio. El tiempo de inicio aumentó ligeramente y la tasa de incidentes cayó dramaticamente. A veces “rápido” es solo “frágil con mejor marketing.”

Microhistoria #3: La práctica aburrida pero correcta que salvó el día

En un entorno regulado, un equipo tenía servidores Ubuntu que ocasionalmente necesitaban trabajo de consola en emergencias. Tenían una política que parecía anticuada: cada respuesta a incidentes empezaba capturando estado, incluyendo extractos de journalctl -b y una instantánea de las rutas de sockets en /run, antes de cualquier reinicio.

Parecía burocrático hasta que un host de producción empezó a lanzar errores de conexión D-Bus después de una actualización de kernel. El on-call siguió la política. Capturó findmnt /run, comprobó espacio libre, verificó que /run/systemd/private existiera y notó que /run/dbus/system_bus_socket faltaba. También capturó logs tempranos que mostraban advertencias del montaje tmpfs.

Porque tuvieron evidencia, no hicieron tonterías. Encontraron que /run se había montado en modo solo lectura debido a una sutil falla de initramfs/mount. Con eso corregido y un reinicio controlado, el socket del bus apareció, systemctl se recuperó y el incidente terminó limpiamente.

La práctica aburrida no solo arregló la máquina; preservó la narrativa. En entornos corporativos, la narrativa es la mitad de la recuperación: necesitas explicar qué pasó sin culpar a los rayos cósmicos.

Listas de verificación / plan paso a paso

Checklist A: Ves “Failed to get D-Bus connection” al ejecutar systemctl (ámbito sistema)

  1. Confirma que estás en el host y que PID 1 es systemd (Task 2).
  2. Comprueba el montaje y la capacidad de /run (Task 6).
  3. Verifica que /run/dbus/system_bus_socket exista (Task 3).
  4. Revisa systemctl status dbus dbus.socket (Task 4).
  5. Comprueba el socket privado de systemd /run/systemd/private (Task 18).
  6. Prueba la respuesta del bus con busctl --system list (Task 17).
  7. Extrae logs: journalctl -b y unidades relevantes (Task 12).
  8. Si debes reiniciar, hazlo deliberadamente: logind → dbus → daemon-reexec (Task 20).

Checklist B: Ves el error al ejecutar systemctl –user o herramientas de escritorio (ámbito sesión de usuario)

  1. Comprueba XDG_RUNTIME_DIR y DBUS_SESSION_BUS_ADDRESS (Task 7).
  2. Verifica que /run/user/UID y /run/user/UID/bus existan y sean propiedad del usuario (Task 8).
  3. Comprueba systemctl --user status (Task 9).
  4. Usa loginctl list-sessions y loginctl show-user (Task 10).
  5. Si esto ocurre por SSH/cron, decide: ¿necesitas una sesión real o un servicio del sistema?
  6. Si necesitas servicios de usuario en segundo plano, habilita lingering para ese usuario (Task 16), luego prueba de nuevo.
  7. Si el directorio runtime sigue desapareciendo, arregla el ciclo de vida de la sesión y PAM (Task 14/15).

Checklist C: Estás en automatización/CI y falla

  1. Confirma si estás en un contenedor y PID 1 no es systemd (Task 2).
  2. Deja de intentar usar systemctl en ese entorno. Ejecuta el servicio directamente o rediseña el job.
  3. Si realmente requieres systemd, ejecuta un entorno compatible con systemd de forma intencional, no accidental.

Broma #2: Reiniciar dbus sin comprobar sockets es como reiniciar una impresora porque te quedaste sin papel—cathártico, ineficaz y extrañamente popular.

Preguntas frecuentes

1) ¿Por qué usa systemctl D-Bus en absoluto?

systemctl es un cliente. Habla con las APIs del gestor systemd, comúnmente expuestas vía D-Bus y el socket privado de systemd. Sin bus, no hay conversación.

2) Veo dbus-daemon en ejecución. ¿Por qué sigo obteniendo el error?

Porque que el proceso exista no es lo mismo que el socket sea accesible en tu namespace/contexto. Comprueba las rutas de socket bajo /run y confirma que estés en el namespace de montaje del host (Task 3, 6, 19).

3) ¿Qué cambia entre “No such file or directory” y “Permission denied”?

No such file generalmente significa que la ruta del socket no existe en tu vista (montaje /run faltante, directorio runtime ausente, problema de namespace). Permission denied significa que el socket existe pero el control de acceso te bloquea (usuario incorrecto, política o confinamiento).

4) ¿Por qué solo falla por SSH?

O bien tu sesión SSH no está registrada con logind (misconfiguración de PAM), o estás ejecutando dentro de un wrapper/chroot restringido. Verifica pam_systemd.so y comprueba si se crea /run/user/UID para esa sesión (Task 10, 14).

5) ¿Es seguro habilitar lingering?

Es seguro cuando sabes por qué lo necesitas: ejecutar servicios de usuario sin inicios de sesión activos. Es inseguro como solución general porque mantendrás gestores de usuario vivos, lo que puede ocultar bugs de logout y desperdiciar recursos. Habilítalo por usuario, deliberadamente (Task 16).

6) ¿Puedo simplemente exportar DBUS_SESSION_BUS_ADDRESS y seguir?

Puedes, pero no deberías. Exportar direcciones obsoletas es como crear “funciona en mi shell” fantasmas que fallan después. Prefiere establecer una sesión real y dejar que logind/systemd ponga XDG_RUNTIME_DIR y la dirección del bus.

7) ¿Cuál es la forma más rápida de diferenciar bus del sistema vs bus de usuario?

Si usas systemctl sin --user, es ámbito del sistema. Si el socket relevante es /run/dbus/system_bus_socket, es el bus del sistema. Si es /run/user/UID/bus, es el bus de la sesión de usuario.

8) Estoy en una instalación de servidor mínima—¿necesito dbus-user-session?

Si ejecutas servicios en ámbito de usuario o esperas que las sesiones de usuario tengan un bus de sesión adecuado, sí, a menudo es necesario. Si solo gestionas servicios del sistema, a veces puedes evitarlo. Respuesta guiada por síntomas: si falta el bus de usuario, comprueba la presencia del paquete (Task 13).

9) ¿Por qué systemctl --user falla como root incluso cuando el usuario está conectado?

Porque el entorno de root no es el entorno del usuario, y root no está “adjunto” a ese bus de sesión de usuario. Ejecuta el comando como el usuario en la sesión, o usa herramientas adecuadas para apuntar a ese gestor de usuario.

10) ¿Cuándo reinicio en lugar de depurar?

Si PID 1 está poco saludable, /run está corrupto/solo lectura, o los sockets de systemd faltan y no puedes recuperarlos limpiamente, un reinicio controlado suele ser la solución más fiable. Captura logs primero.

Conclusión: próximos pasos que puedes desplegar hoy

“No se pudo obtener la conexión D-Bus” no es una invitación a reiniciar servicios al azar. Es una petición para verificar un contrato: /run está montado y escribible, el socket correcto existe, tu sesión es real y tu entorno apunta al bus correcto.

Haz esto a continuación:

  1. Ejecuta el guion rápido: sockets, directorios runtime, sesiones logind. No te saltes a los reinicios.
  2. Decide si tu flujo de trabajo depende del bus de usuario. Si es así, estandariza rutas de inicio (PAM + logind) y evita cron para trabajo de sesión.
  3. Si esto es un problema en la flota, añade una comprobación ligera: verificar que /run/dbus/system_bus_socket y /run/systemd/private existan, y alertar sobre directorios runtime faltantes para sesiones activas.
  4. Escribe la regla de contexto: chroots/containers pueden fallar en systemctl. Tus runbooks deberían decirlo claramente.
← Anterior
RAID no es respaldo: la frase que la gente aprende demasiado tarde
Siguiente →
Extrañezas de red en Docker Desktop: acceso LAN, puertos y soluciones DNS que realmente funcionan

Deja un comentario