ECONNRESET retry storms correlate to-the-second with usage-credit boundary events — edge resets connections instead of returning 429
Summary
Claude Code v2.1.220 (macOS, native install, latest) intermittently fails with Unable to connect to API (ECONNRESET) · Retrying… in 3–8 minute episodes, several times a day, on a machine whose network path was verified healthy during the exact failure windows. After ruling out every local layer, the evidence points to server-side connection resets tied to usage-limit boundary events — the edge appears to sometimes reset connections instead of answering with a clean HTTP 429 — and the CLI's ~3-minute 10-attempt retry ladder amplifies each blip into a multi-minute visible outage.
We root-caused this with ClawMetry (open-source observability for coding agents) running on the affected machine, which made it possible to build a strict cross-session error timeline and correlate it with account limit state.
Evidence
1. Network exonerated during episodes, not just around them
- macOS unified log: zero Wi-Fi roam/DHCP/link/interface events inside the failure windows; kernel accepted 200+ new outbound TCP connections normally during an episode.
- 5 fresh unauthenticated
curl https://api.anthropic.com/calls succeeded in ~80 ms while a session displayed "Retrying… attempt 7/10". - No proxy/VPN/MITM — verified at the wire with
lsof: sessions connect directly to160.79.104.10:443. IPv4 only, clean MTU 1500, 0% packet loss, no status-page incident posted for the affected days.
2. To-the-second correlation with usage-credit boundary events (2 out of 2 observed crossings)
2026-08-02 13:14:09 UTC: session A's first request returned "You're out of usage credits · resets 4pm" with a requestId (an HTTP-level refusal — the API was fully reachable). The same second, sibling sessions began ECONNRESET retry ladders, and a fresh session's first-ever attempt got ECONNRESET — yet its retry succeeded 4 s later. Successes resumed 45 minutes before the advertised reset.2026-07-31 21:02–21:04 UTC: the same credit refusals (with requestIds) sat inside an ECONNRESET cluster spanning 20:18–23:20 UTC.- Within a single 60-second window on one account we observed all three outcomes interleaved: clean HTTP refusal, TCP reset, and success. That looks like racy/per-shard limit enforcement where some paths terminate the connection rather than returning 429 + the standard
anthropic-ratelimit-unified-*headers.
3. The retry ladder is the pain amplifier
- 23/23 sampled errors show an identical signature: a 175–192 s silent gap (the full 10-attempt backoff ladder, all failing) on a fresh request started ~1 s after a successful tool_result — never mid-stream.
- A manual user retry immediately after the error succeeded in 4–17 s in every sampled case. So users wait ~3 minutes for a failure that a fresh attempt resolves in seconds. Related long-standing reports: #23744, #48008.
4. Token burn does not correlate
Per-15-min weighted burn vs error placement across 2,564 deduplicated API responses: errors land in top-quartile burn buckets less often than chance (21% vs 25%), the heaviest buckets were error-free, and one error fell in a zero-burn bucket. It's the limit boundary transitions that coincide with episodes, not load itself.
Environment
- claude-code 2.1.220 (native install), macOS (Darwin 25.3.0)
- Direct connection, no proxy; IPv4 only; DNS 1.1.1.1/8.8.8.8
- Heavy parallel usage (many concurrent sessions and subagents)
Diagnosis method (reproducible)
Strict error timeline extracted from session transcripts (only type:system, subtype:api_error entries and literal API Error: assistant messages — naive grepping also counts conversations about the error), correlated against macOS unified logs, wire-level socket state, and the official anthropic-ratelimit-unified-5h/-7d/-overage response headers (the same probe ClawMetry's limit meter uses). A per-minute unauthenticated path probe is now armed on the machine; happy to attach its data from the next episode.
Suggested fixes
- If unified-limit enforcement can terminate in-flight or new connections at boundary transitions, surface it as an HTTP error with the standard
anthropic-ratelimit-unified-*headers instead of a TCP reset — the CLI would then show the real cause instead of "Unable to connect". - Make the first 1–2 retries near-immediate (the data shows fresh attempts succeed within seconds), and/or hint "check /usage" when ECONNRESET clusters coincide with a limit boundary.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗