Wer Claude Code mit einem Pro-, Max- oder Team-Abo auf Servern, in Containern oder in CI betreibt, sieht irgendwann die Meldung «Login expired · Please run /login». Laufende Agenten brechen dann mitten in der Arbeit ab. Der Artikel erklärt, wie die Abo-Anmeldung aufgebaut ist, was die offizielle Dokumentation zu abgelaufenen Anmeldungen sagt und wie der Befehl claude setup-token einen Schlüssel mit einem Jahr Laufzeit erzeugt. Dazu kommen der Ablauf Schritt für Schritt, die Rangfolge der Anmeldearten, zwei Stolpersteine aus der Praxis (der nur einmal gezeigte Schlüssel und ein Hook, der im Container fehlt), die Grenzen des Schlüssels und eine Sicherheitsliste für Ablage, Rotation und Widerruf.
Inhalt 12 Abschnitte
- Auf einen Blick
- Das Problem: Agenten brechen mitten in der Arbeit ab
- Wie die Abo-Anmeldung aufgebaut ist
- Die Lösung: claude setup-token
- Welche Anmeldeart gewinnt
- Zwei Stolpersteine aus der Praxis
- Grenzen des Langzeit-Schlüssels
- Sicherheit: Behandle den Schlüssel wie ein Passwort
- Einordnung: Was das für Admins und Entwickler heisst
- Fazit
- Quellen
- Änderungshistorie

Ein Befehl, ein Browser-Klick, ein Schlüssel mit einem Jahr Laufzeit: claude setup-token beendet das ständige Neuanmelden von Claude Code auf Servern und in Containern. Er hat Grenzen, und er verlangt Sorgfalt bei der Ablage.
Auf einen Blick
claude setup-tokenerzeugt einen Schlüssel mit einem Jahr Laufzeit. Er braucht ein Pro-, Max-, Ultra-, Team- oder Enterprise-Abo und kommt als UmgebungsvariableCLAUDE_CODE_OAUTH_TOKENzum Einsatz.- Der Schlüssel erscheint nur einmal. Das Werkzeug speichert ihn nirgends; Du legst ihn selbst ab.
- Er darf nur Modellanfragen stellen. Remote-Control-Sitzungen und claude.ai-Connectors brauchen die normale Anmeldung.
- Pro Maschine ein eigener Schlüssel, Rechte 600, nie ins Git. Das Ablaufdatum gehört in den Kalender.
Das Problem: Agenten brechen mitten in der Arbeit ab
Wer Claude Code mit Abo betreibt, kennt die Meldung Login expired · Please run /login. Im Skript- oder SDK-Betrieb lautet der Text OAuth session expired and could not be refreshed, der Fehlercode authentication_failed. Ein laufender Agent bleibt dann stehen und wartet auf ein Login, das niemand eintippt.
Ein Beispiel aus der Praxis: Auf einem kleinen Linux-Server liefen mehrere Claude-Code-Sitzungen dauerhaft. Dazu kam ein Container, der dieselbe Anmeldedatei ~/.claude/.credentials.json als Volume eingebunden hatte. Alle paar Tage meldeten die Agenten den Ablauf und brachen ab.
Das trifft nicht nur Server. Dieselbe Lage entsteht bei Dev-Containern, bei Pipelines, bei Cron-Aufträgen und bei jedem Rechner, an dem niemand sitzt, wenn die Anmeldung ausläuft.
Wie die Abo-Anmeldung aufgebaut ist
Die Anmeldung per /login besteht aus zwei Teilen. Der Zugriffsschlüssel ist kurzlebig; in der Datei der beschriebenen Maschine lag sein Ablauf bei rund 8 Stunden. Der Erneuerungsschlüssel holt bei Bedarf Ersatz. Auf Linux liegt beides in ~/.claude/.credentials.json mit Dateimodus 0600.
Die Dokumentation beschreibt, was beim Scheitern passiert. Lehnt der OAuth-Dienst den Erneuerungsschlüssel ab, löscht Claude Code die Zugangsdaten. Danach bricht jede Modellanfrage lokal mit Login expired ab, bis jemand /login ausführt. Für Hintergrundsitzungen und Remote-Control-Sitzungen weist die Dokumentation ausdrücklich darauf hin: Sie kommen nach Ablauf nicht von selbst weiter.
Vermutung: Warum der Erneuerungsschlüssel im beschriebenen Aufbau abgelehnt wurde, belegt die Dokumentation nicht. Plausibel ist dieser Ablauf: Mehrere Prozesse erneuern dieselben Zugangsdaten, der Erneuerungsschlüssel wechselt dabei, und ein Nachzügler hält noch den alten. Auf demselben Rechner koordiniert laut Dokumentation eine gemeinsame Sperre das Erneuern. Ob sie im Container mit eigenem Prozessraum greift, ist offen.
Die Lösung: claude setup-token
Der Befehl öffnet denselben Browser-Ablauf wie /login und gibt nach der Freigabe einen Schlüssel mit einem Jahr Laufzeit aus. Der angeforderte Umfang im Link lautet user:inference. Die Dokumentation nennt dafür CI-Pipelines und Skripte, in denen kein Browser-Login möglich ist.
- 1Befehl startenclaude setup-token in einer Sitzung, die offen bleibt
- 2Im Browser bestätigenLink öffnen, anmelden, Code einfügen
- 3Schlüssel sofort sichernEr wird nur einmal gezeigt
- 4Rechte 600 setzenDatei nur für den eigenen Benutzer lesbar
- 5Variable setzenCLAUDE_CODE_OAUTH_TOKEN im Container, Skript oder CI
- 6Prüfen mit /statusZeile Auth token muss die Variable nennen
Die Ausgabe nennt den Weg, ihn per export CLAUDE_CODE_OAUTH_TOKEN=<token> zu setzen, und warnt, dass er nicht erneut erscheint. Der Platzhalter steht hier absichtlich so; ein echter Schlüssel gehört nie in einen Text, ein Ticket oder einen Chat.
# 1. Schlüssel erzeugen (Sitzung offen lassen, bis er gesichert ist) claude setup-token # 2. Sofort ablegen, nur für den eigenen Benutzer lesbar umask 077 printf '%s\n' '<token>' > ~/.config/claude-token chmod 600 ~/.config/claude-token # 3. In docker-compose über eine .env-Datei übergeben # .env: CLAUDE_CODE_OAUTH_TOKEN=<token> # docker-compose: environment: [ CLAUDE_CODE_OAUTH_TOKEN ] docker compose up -d --force-recreate
Im Beispielserver lief der Aufruf im Container danach wieder, ohne dass jemand /login ausführen musste.
Welche Anmeldeart gewinnt
Sind mehrere Zugangsdaten vorhanden, wählt Claude Code nach einer festen Rangfolge. Die Tabelle zeigt die Arten, die für Abo-Betrieb und Automatisierung zählen, von hoher zu niedriger Priorität.
| Anmeldeart | Gültigkeit | Bemerkung |
|---|---|---|
ANTHROPIC_API_KEY |
bis zum Widerruf |
Abrechnung pro Token über die API, im Modus -p immer genutzt |
apiKeyHelper |
vom Hilfsprogramm bestimmt |
Für wechselnde Schlüssel aus einem Tresor |
CLAUDE_CODE_OAUTH_TOKEN |
ein Jahr |
Abo, nur Modellanfragen, ohne Remote Control |
/login (Abo) |
Zugriff kurz, Erneuerung automatisch |
Voller Funktionsumfang, läuft ab, wenn die Erneuerung scheitert |
Zwei Folgen sind wichtig. Ist ANTHROPIC_API_KEY gesetzt, rechnet Claude Code darüber ab, nicht über das Abo; wie sich das auswirkt, beschreibt der Artikel Claude Code in Cursor: Drei Abos, ein Fenster. Zudem bleibt CLAUDE_CODE_OAUTH_TOKEN stehen, wenn eine Anfrage mit 401 scheitert; Claude Code wechselt dann nicht auf eine gespeicherte Anmeldung. Die Dokumentation rät für den Fall, den Schlüssel neu zu erzeugen oder die Variable zu entfernen und /login auszuführen.
Zwei Stolpersteine aus der Praxis
Der Schlüssel war weg. Im Beispiel schloss sich das Terminalfenster nach der Ausgabe. Weil er nur einmal erscheint, blieb ein neuer Durchlauf. Lass die Sitzung deshalb in tmux oder screen offen und kopiere den Schlüssel, bevor Du sie schliesst. Lege ihn sofort mit Rechten 600 ab.
Ein Hook fehlte im Container. Nach dem Neuerstellen blockierte ein UserPromptSubmit-Hook jeden Aufruf mit «UserPromptSubmit operation blocked by hook … No such file or directory». Die eingebundene settings.json stammte vom Host und nannte einen Hook-Pfad, den es im Container nicht gab. Gelöst hat es, den Hook-Ordner unter demselben Pfad read-only einzubinden. Alternativ bekommt der Container eine eigene, schlanke settings.json.
Grenzen des Langzeit-Schlüssels
Laut Dokumentation darf er nur Modellanfragen stellen. Er baut keine Remote-Control-Sitzungen auf und holt keine claude.ai-Connectors. Lokal konfigurierte MCP-Server laufen weiter. Der Bare-Modus (--bare) liest die Variable nicht; dort greifst Du auf ANTHROPIC_API_KEY oder apiKeyHelper zurück.
Zusätzlich gilt: Wer forceLoginOrgUUID in den verwalteten Einstellungen setzt, prüft damit bei setup-token nur die Anmeldemethode, nicht die Organisation. Admins sollten wissen, dass sich damit ein Token für eine andere Organisation erzeugen lässt.
Für Sitzungen, die Remote Control oder Connectors brauchen, bleibt die normale Anmeldung. Die Dokumentation empfiehlt, sie rechtzeitig zu erneuern; eine Warnung erscheint drei Tage vor Ablauf.
Sicherheit: Behandle den Schlüssel wie ein Passwort
Wer ihn besitzt, nutzt Dein Abo. Die Dokumentation zu Dev-Containern warnt zudem, dass im Container erreichbare Anmeldedaten bei einem bösartigen Projekt abfliessen können. Daraus folgen diese Regeln:
- Nie ins Git.
.envsteht in der.gitignore; in CI gehört der Schlüssel in den Secret-Speicher der Plattform. - Rechte 600 für jede Datei, die ihn enthält, oder ein Secret-Store statt einer Datei.
- Ein Schlüssel je Maschine und Zweck. So lässt sich ein einzelner ersetzen, ohne alle anderen zu stören.
- Ablaufdatum in den Kalender. Ein Jahr vergeht schnell; plane die Erneuerung zwei Wochen vorher.
- Widerruf bereithalten. Die Dokumentation kennt den Zustand «OAuth token revoked», etwa nach dem Abmelden auf allen Geräten oder wenn ein Admin den Zugang entzieht. Ob das auch einen Langzeit-Schlüssel trifft, nennt sie nicht. Teste den Widerruf einmal, bevor Du ihn im Ernstfall brauchst, und erzeuge danach neue Schlüssel.
- Keine Host-Geheimnisse mitmounten. Binde nur ein, was der Container braucht, und zeige Schlüssel nie in Logs oder Chats.
Wer API-Schlüssel statt Abo nutzt, findet Hinweise zu Limits und Kosten im Artikel Claude API im Betrieb: Schlüssel, Limits, Kosten.
Einordnung: Was das für Admins und Entwickler heisst
Für unbeaufsichtigte Läufe ist der Langzeit-Schlüssel die vorgesehene Lösung der Dokumentation, nicht ein Umweg. Er ersetzt das Neuanmelden durch einen jährlichen Wechsel, den Du planen kannst. Der Preis ist eine zweite Art von Geheimnis, die Du verwalten musst. Rechne deshalb Ablage, Rotation und Widerruf ein, bevor Du den ersten Schlüssel erzeugst. Wer Sitzungen mit Remote Control oder Connectors braucht, hält dafür weiter eine normale Anmeldung bereit.
Fazit
Wiederkehrende Abbrüche mit Login expired lassen sich auf Servern, in Containern und in CI mit einem Befehl beenden. claude setup-token liefert einen Schlüssel für ein Jahr, der nur Modellanfragen erlaubt. Sichere ihn sofort, setze ihn als CLAUDE_CODE_OAUTH_TOKEN und prüfe mit /status. Behandle ihn dann wie jedes andere Passwort.
Quellen
- Claude Code: Authentication (Abschnitte «Generate a long-lived token», «Authentication precedence», «Credential management»)
- Claude Code: Error reference (Abschnitte «Login expired» und «OAuth token revoked or expired»)
- Claude Code: Development containers (Anmeldung im Container und Codespaces-Secrets)
Geschrieben von Andreas Brauckmann · So arbeitet die Redaktion
Änderungshistorie
- — Artikel veröffentlicht: Langzeit-Schlüssel für Claude Code auf Servern, in Containern und in CI.