Remote Control WebSocket disconnects every ~25 min, permanently dies after 3rd reconnect (1006 → 1002)
Summary
Claude Code's Remote Control feature disconnects repeatedly due to server-side WebSocket closures, eventually giving up permanently. SSH and screen sharing to the same machine remain stable — only the Remote Control WebSocket is affected.
Environment
- Machine: Mac Mini (Apple Silicon), macOS, hardwired ethernet
- Network: 867 Mbps down, 874 Mbps up, 10ms latency (verified via
networkQuality) - Claude Code version: Latest as of 2026-03-07
- Power settings:
sleep 0,displaysleep 0,standby 0,powernap 0,tcpkeepalive 1— machine never sleeps - Uptime: 15+ hours, zero sleep/wake transitions
Behavior
The WebSocket connection to api.anthropic.com/v1/session_ingress/ws/... follows a repeatable pattern:
- Connects successfully
- Keep-alive pings sent every 5 minutes (working correctly)
- ~25 minutes later, server drops the connection with close code 1006 (abnormal closure — no close frame sent)
- Client reconnects successfully within ~1 second
- Steps 2–4 repeat two more times (cycle is ~25 min each)
- On the 3rd reconnect attempt, server responds with close code 1002 (protocol error)
- Client treats 1002 as permanent and stops reconnecting:
````
WebSocketTransport: Permanent close code 1002, not reconnecting
[bridge:repl] Reconnect exhausted (code=1002), falling back to poll loop
- Remote Control shows as disconnected in the UI. Only manual
/remote-controltoggle restores it.
Evidence from debug logs
Two independent sessions show the exact same pattern at the exact same timestamps, confirming this is server-side:
Session 1 (~/.claude/debug/07e4a19b-...txt)
00:29:39 keep_alive sent
00:29:45 [ERROR] Closed: 1006 → reconnect → Connected
00:54:47 keep_alive sent
00:54:53 [ERROR] Closed: 1006 → reconnect → Connected
01:19:54 keep_alive sent
01:20:01 [ERROR] Closed: 1006 → reconnect attempt
01:20:02 [ERROR] Closed: 1002 → Permanent close, not reconnecting
Session 2 (~/.claude/debug/4b43221f-...txt)
00:29:38 keep_alive sent
00:29:44 [ERROR] Closed: 1006 → reconnect → Connected
00:54:45 keep_alive sent
00:54:52 [ERROR] Closed: 1006 → reconnect → Connected
01:19:53 keep_alive sent
01:19:59 [ERROR] Closed: 1006 → reconnect attempt
01:20:01 [ERROR] Closed: 1002 → Permanent close, not reconnecting
Both sessions disconnect within 1 second of each other at each cycle — this is not a client or network issue.
What was ruled out
- No system sleep events —
pmset -g logshows zero sleep/wake transitions - No network interface changes — ethernet link stayed up, no flaps in system logs
- No kernel or powerd disruptions — only benign hourly DarkWake probes (unrelated)
- SSH and screen sharing remain connected indefinitely to the same machine
- Network quality is excellent — sub-10ms latency, ~870 Mbps both directions
Expected behavior
- The WebSocket should not be dropped every 25 minutes while keep-alives are being sent
- If it is dropped, reconnection should not be permanently abandoned after 3 attempts — it should continue retrying with backoff since the connection does successfully re-establish each time
- At minimum, the client should not treat a transient 1002 as permanent when the prior reconnects all succeeded
Suggested improvements
- Server-side: Investigate why the WebSocket gateway is closing connections every ~25 min despite active keep-alives
- Client-side: Don't treat 1002 as permanently fatal after successful prior reconnects — use exponential backoff and keep retrying
- Client-side: Surface the "fell back to poll loop" state more clearly in the UI so users know what happened
🤖 Filed with help from Claude Code
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗