`claude remote-control` server exits on 401 after exactly 24h — does not refresh its OAuth access token, killing every attached session
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report
- [x] I am using the latest version of Claude Code
Version: 2.1.233 (npm global) · macOS 15 (Darwin 25.6.0) · Apple Silicon Mac mini · Max subscription
Summary
A long-running claude remote-control server dies exactly 24 hours after the process starts, with a 401 "OAuth access token has expired". It does not attempt a refresh, and it does not re-read the refreshed credentials that are already on disk. Every Remote Control session attached to that server is orphaned the instant it exits — the phone/web client shows the environment as gone, and in-flight work (running subagents, uncommitted edits) is lost.
The 24h figure is not approximate. Two independently-started servers on the same machine:
| Server | Started | Died | Lifetime |
|---|---|---|---|
| rc-claude | Aug 18 13:23:03 | Aug 19 13:23:09 | 24h 00m 06s |
| rc-hardware / rc-software / rc-workflows | Aug 18 13:01:51 | Aug 19 13:01:53 | 24h 00m 02s |
The second row is three servers dying in the same second, having been launched in the same second.
Exact error
Captured from the tmux pane at the moment of exit (process exit status 0):
[13:23:09] Error: Poll: Authentication failed (401): OAuth access token has expired.
Re-authenticate to continue.. Remote Control is only available with claude.ai
subscriptions. Please use `/login` to sign in with your claude.ai account.
Note the doubled period in continue.. — likely two message strings concatenated.
The credentials on disk were valid
This is the key point: the machine's auth was fine. At the moment the server died holding an "expired" token, ~/.claude/.credentials.json contained:
claudeAiOauth.expiresAt = 2026-08-19 19:30:38 (6h in the future)
claudeAiOauth.refreshTokenExpiresAt = 2026-09-14 06:51:40 (26 days in the future)
file mtime = 2026-08-19 11:30:38 (refreshed 2h earlier)
So another claude process had already refreshed the token successfully. The remote-control server appears to hold the access token it obtained at startup in memory for its whole life, never refreshing it and never re-reading the file. /login is not the fix — restarting the process is, which is why "run claude again" appeared to fix earlier incidents.
Expected
The server refreshes its access token before expiry (the refresh token is valid for weeks) and keeps serving. A 401 on a poll should trigger a refresh-and-retry, not process exit.
Actual
Process exits with status 0. Every attached session is orphaned with no warning, at a time of day determined by whenever the server last happened to start.
Impact
The exit time inherits the server's start time, so the failure lands mid-workday for anyone whose server was last restarted mid-workday. In our case it landed at 13:01 on two consecutive days, twice killing active sessions with running subagents. Because it presents as "the environment no longer exists" on the client, it reads as a network or account problem — we chased a network-outage theory and a watchdog theory for two days before catching the actual error, since the pane is erased on exit.
Reproduce
- Start
claude remote-control --name Xon a machine and leave it running. - Attach one or more sessions from the mobile/web client.
- Wait 24 hours (no interaction needed; it dies whether idle or busy — our idle server and our 3-session server both died at their own 24h marks).
- The server exits with the 401 above; attached sessions are unrecoverable in place.
Why I think this is distinct from the RC credential path already reported
#78453 shows the RC client fetching remote credentials from a /bridge endpoint at session-creation time — i.e. Remote Control mints and holds a credential of its own rather than using the account access token directly. That fits what I see: my account access token rotates on a several-hour cycle (the file showed an 8h validity window and had been refreshed 2h before the crash), yet the server survived a clean 24h from process start, twice. So the expiring thing looks like an RC-specific credential obtained once at startup and never renewed for the life of the process.
Related issues
Same root class (token refresh in long-lived processes), but none covers a remote-control server exiting at its own 24h mark:
- #87271 — desktop app: OAuth refresh is reactive-only, surfacing on every ~2h rotation. Same underlying "refresh is not proactive" theme, different surface and different interval.
- #82217 — OAuth expiration not propagated to active subagent requests; long-running sessions "all broke overnight" with simultaneous 401s. Closest in spirit; that report is about subagent requests inside a session, not the RC server process exiting.
- #83958 —
claude remote-control401 at the Registration phase with "Missing Authorization header". Different phase, different message, and it fails at startup rather than after 24h of healthy service. - #78453 — 401 at the
/bridgeendpoint after session creation. Different phase; cited above as evidence for the separate-RC-credential hypothesis.
Suggested fixes
- Refresh the OAuth access token proactively in the remote-control server, or on a 401 retry the request once after refreshing.
- Failing that, re-read
~/.claude/.credentials.jsonon 401 before giving up — in our case a valid token was sitting there. - Do not exit 0 on a fatal auth error, and write the reason to stderr as well as the TUI. The alternate-screen restore wipes the message on exit, which is what made this undiagnosable for two days.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗