daemon-auth-status.json stays stuck at auth_required after the daemon recovers

Open 💬 0 comments Opened Jul 16, 2026 by mholzum

Description

After the background daemon (claude daemon run) hits a headless-OAuth failure and later self-recovers, the on-disk auth sentinel ~/.claude/daemon-auth-status.json is never rewritten to reflect the recovery. It stays stuck at {"status":"auth_required",...} indefinitely, even though daemon.log shows auth working normally afterward (proactive refreshes succeeding, sessions completing) and even across a subsequent version self-update.

This is confusing for anything that inspects that file to decide whether headless/unattended claude -p calls are safe to run (e.g. a monitoring script) — it reports a stale incident as current, with no expiry or reconciliation.

Repro / evidence from ~/.claude/daemon.log

[2026-07-15T22:58:12.932Z] [supervisor] auth: proactive refresh starting
[2026-07-15T22:58:13.089Z] [supervisor] auth: proactive refresh failed, retrying in ~60s (token still valid)
... (retries every 60s) ...
[2026-07-15T23:02:13.484Z] [supervisor] auth: proactive refresh starting
[2026-07-15T23:02:13.606Z] [supervisor] auth: proactive refresh failed, signalling re-auth required
[2026-07-15T23:02:13.613Z] [supervisor] auth: headless daemon cannot complete OAuth — run `claude auth login` to refresh
[2026-07-15T23:02:13.614Z] [supervisor] auth: no token found, will re-check keychain every 30s
[2026-07-16T02:47:43.137Z] [supervisor] auth: scheduling proactive refresh in 28560s
[2026-07-16T02:47:43.138Z] [supervisor] auth: token refreshed via keychain re-check retry
[2026-07-16T02:58:29.656Z] [supervisor] binary at ... changed (2.1.210 -> 2.1.211) -- self-restarting for upgrade
... (daemon runs normally afterward, proactive refreshes succeed) ...

At the moment of the 23:02:13.613Z event, two files are written:

~/.claude/daemon-auth-cooldown        -> 1784156533608
~/.claude/daemon-auth-status.json     -> {"status":"auth_required","since":1784156533613}

Despite the daemon recovering (02:47:43Z) and running cleanly for many hours afterward (including through a version upgrade and multiple successful headless -p invocations), ~/.claude/daemon-auth-status.json still reads exactly the same stale auth_required payload from the original 23:02:13 event, unchanged, hours later. Confirmed by re-reading the file live while headless claude -p calls in the same environment were completing successfully in 2-4 seconds.

Expected behavior

daemon-auth-status.json (and/or daemon-auth-cooldown) should be cleared or rewritten to reflect a successful recovery once the daemon's own auth state recovers (e.g. on the next successful proactive refresh or keychain re-check), so the file's contents match daemon.log's actual state instead of freezing at the last failure.

Environment

  • claude --version: 2.1.211 (also observed on 2.1.210, i.e. pre-dates this specific version)
  • OS: macOS (Darwin)
  • Auth mode: subscription/OAuth via Keychain-stored "Claude Code-credentials" item (not ANTHROPIC_API_KEY)
  • Daemon architecture: background claude daemon run supervisor process with bg-spare workers

Impact

Low severity on its own (headless -p invocations do not appear to actually gate on this file — confirmed by direct testing), but it's a misleading signal for anything built on top of it, and worth fixing so the sentinel is trustworthy.

View original on GitHub ↗