OpenClaw im Crash-Loop: Plugin-Consent, fehlender D-Bus und ein Update, das nie durchlief

Ausgangslage

OpenClaw läuft in meinem Homelab nativ auf einer Debian-13-VM, nicht in Docker. Der Gateway ist ein systemd-User-Service unter root, ein Timer stösst jede Nacht ein Update an. Über den Gateway laufen das Webinterface und ein Telegram-Bot, der mir unter anderem Wetter- und Update-Berichte schickt. Der Reverse Proxy sitzt auf einem separaten Host.

Problem

Eines Morgens waren Webinterface und Bot tot. Ein Blick auf systemctl --user status openclaw-gateway zeigte activating (auto-restart), im Journal stand ein Restart-Zähler von über 14’000. Der Gateway kam also nie richtig hoch, sondern scheiterte alle paar Sekunden von Neuem.

Im Log stand der eigentliche Grund: Das Web-Search-Plugin «duckduckgo» verlange eine Zustimmung zu seinen Berechtigungen, und ohne diese verweigere der Gateway den Start («refusing to report the gateway ready»). systemd startete ihn daraufhin endlos neu.

Beim Nachforschen kamen zwei weitere Probleme ans Licht:

Die Installation des Plugins hing ohne Ausgabe. Netzwerk und npm waren in Ordnung, aber die Versionen passten nicht zusammen: Das Plugin stand auf 2026.9.5, das CLI noch auf 2026.8.2. Das nächtliche Update war also schon länger stillschweigend gescheitert.

Im Update-Log stand ausserdem immer wieder «Gateway service inspection is unavailable» und «systemd user session bus is unavailable». Unter /run/user/0/bus gab es schlicht keinen User-Bus.

Auflösung

Schritt 1: Gateway ohne Plugin hochbringen. Als Notlösung habe ich zuerst ein Backup der openclaw.json angelegt und danach den Plugin-Eintrag und den Suchprovider aus der Konfiguration entfernt. Der Gateway ignoriert die Websuche dann und startet normal. Wichtig: Beim Bearbeiten der Konfiguration keine Tokens in Logs oder Screenshots zeigen, denn sie liegen im Klartext in der Datei.

Schritt 2: OpenClaw sauber aktualisieren. Ich habe den Gateway gestoppt, openclaw update --no-restart ausgeführt, danach openclaw doctor --fix --non-interactive laufen lassen und den Gateway wieder gestartet. Danach lief alles auf 2026.9.5. Das Plugin liess sich nun mit openclaw plugins install @openclaw/duckduckgo-plugin --accept-capabilities problemlos installieren, die Berechtigungen habe ich dabei bewusst bestätigt.

Schritt 3: Die eigentliche Ursache beheben. Auf der VM fehlte das Paket dbus-user-session. Ohne User-Bus kann OpenClaw seinen eigenen Service weder inspizieren noch neu starten und bricht Updates ab, obwohl Linger für root bereits aktiv war. Nach apt install dbus-user-session, dem Setzen von XDG_RUNTIME_DIR und dem Start von dbus.socket war der Bus da.

Danach hat Doctor den Service zum ersten Mal wieder angefasst, den Gateway gestoppt und wegen einer Ownership-Prüfung nicht mehr gestartet. Das war kurz unangenehm, liess sich aber mit einem manuellen Start und anschliessend openclaw gateway install --force beheben. Die alte Unit wird dabei als Sicherung abgelegt, und die Service-Beschreibung passt seither wieder zur installierten Version.

Schritt 4: Das Update-Script anpassen. Ein Timer läuft ohne Login-Umgebung. Im Script fehlten deshalb XDG_RUNTIME_DIR, DBUS_SESSION_BUS_ADDRESS, HOME und PATH. Ohne sie scheiterte der Timer-Lauf mit einem StateDatabaseCoordinatorContentionError: Doctor kam nicht in den Wartungsmodus, weil der laufende Gateway die State-Datenbank blockierte. Nach dem Setzen der vier Variablen übergibt OpenClaw das Update an einen eigenen Hintergrundprozess und beendet sich mit Exit-Code 75. Das ist kein Fehler, sondern die Übergabe. Wer das Ergebnis im Script auswertet, muss 75 deshalb als «übergeben» behandeln und nicht als «fehlgeschlagen».

Lessons Learned

  • Ein Gateway im Crash-Loop ist oft ein Consent- oder Konfigurationsproblem und kein echter Absturz. Die erste Fehlermeldung im Log zeigt den Grund meist sofort.
  • Core und Plugins müssen zusammenpassen. Ein still scheiterndes Auto-Update fällt erst auf, wenn ein Plugin eine neuere Version verlangt. Ein Blick auf npm view und openclaw --version deckt das schnell auf.
  • dbus-user-session gehört auf jede VM, die User-Services unter systemd betreibt. Sonst gehen Updates und Neustarts schief, ohne dass der Gateway selbst etwas merkt.
  • Timer laufen ohne Login-Umgebung. Was in der Shell funktioniert, braucht im Script explizite Variablen.
  • Ein Test mit dem manuellen Start des Update-Dienstes (systemctl start auf den Update-Service) zeigt sofort, ob der Timer-Kontext funktioniert, ohne bis zur nächsten Nacht zu warten.
  • Ein Backup gehört vor jedes Update, und zwar nicht nach /tmp. Das Archiv enthält Tokens und sollte nur für root lesbar sein.
  • Die Doctor-Warnungen ernst nehmen: Klartext-Secrets in der Konfiguration und ein Gateway auf allen Interfaces sind hinter einem Reverse Proxy mit Firewall vertretbar, aber ein Punkt für die To-do-Liste (SecretRefs, Bind auf Loopback).

Fazit

Der Ausfall hatte drei Ebenen: ein Plugin mit fehlender Zustimmung, ein veralteter Core und ein fehlender D-Bus, der Updates unbemerkt verhinderte. Erst die dritte Ebene erklärt, warum es «mal wieder» passierte. Der Gateway läuft jetzt auf der aktuellen Version, die Websuche ist wieder aktiv, und das Update-Script kennt seine Umgebung. Ob die nächtliche Automatik bei einem Release mit echtem Update komplett durchläuft, zeigt sich erst dann. Bis dahin bleibt der Blick ins Update-Log am Morgen Pflicht. Wie ich Updates an anderer Stelle im Homelab automatisiere, steht im Beitrag Semaphore: Von Handarbeit zu automatisierten Updates.

Schreibe einen Kommentar