[BUG] ECONNRESET issues

Open 💬 17 comments Opened Feb 25, 2026 by posborneao

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

❯ review recent code changes
⎿  API Error: Unable to connect to API (ECONNRESET)

What Should Happen?

claude code should work, claude in browser works fine.
anthropic should fix the issue.

Error Messages/Logs

Steps to Reproduce

debug mode shows this in llog:
2026-02-25T15:03:58.658Z [ERROR] Error: Error: 1P event logging: 14 events failed to export (code=ECONNRESET, The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch())
at queueFailedEvents (/$bunfs/root/claude:6410:2350)
at async doExport (/$bunfs/root/claude:6410:1257)
at processTicksAndRejections (native:7:39)
2026-02-25T15:03:58.659Z [ERROR] Error: Error: {"message":"Failed to export 14 events (code=ECONNRESET, The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch())","originalLine":"6410","originalColumn":"1409","line":"6410","column":"1409","sourceURL":"/$bunfs/root/claude","stack":"Error: Failed to export 14 events (code=ECONNRESET, The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch())\n at doExport (/$bunfs/root/claude:6410:1409)\n at processTicksAndRejections (native:7:39)","name":"Error"}
at error (/$bunfs/root/claude:2342:25028)
at <anonymous> (/$bunfs/root/claude:119:92467)
at U7D (/$bunfs/root/claude:119:93011)
at <anonymous> (/$bunfs/root/claude:120:17366)
at processTicksAndRejections (native:7:39)
2026-02-25T15:03:58.659Z [ERROR] [3P telemetry] OTEL diag error: {"message":"Failed to export 14 events (code=ECONNRESET, The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch())","originalLine":"6410","originalColumn":"1409","line":"6410","column":"1409","sourceURL":"/$bunfs/root/claude","stack":"Error: Failed to export 14 events (code=ECONNRESET, The socket connection was closed unexpectedly. For more information, pass verbose: true in the second argument to fetch())\n at doExport (/$bunfs/root/claude:6410:1409)\n at processTicksAndRejections (native:7:39)","name":"Error"}
2026-02-25T15:04:22.964Z [DEBUG] Fast mode unavailable: Fast mode has been disabled by your organization

Claude Model

Opus

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

claude --version 2.1.56 (Claude Code)

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

happens more and more, generally need to reboot computer to fix.

View original on GitHub ↗

17 Comments

github-actions[bot] · 4 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/27789
  2. https://github.com/anthropics/claude-code/issues/25382
  3. https://github.com/anthropics/claude-code/issues/5674

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

posborneao · 4 months ago

#27789 is specific to the API not claude code cli

posborneao · 4 months ago

https://github.com/anthropics/claude-code/issues/25382 show 403 in logs prior to ECONNRESET, which isn't the same

posborneao · 4 months ago
maribox · 3 months ago

I'm constantly getting this and it has happened for half a year now and basically all issues are automatically closed without any response from Anthropic. They are becoming the new GitHub, ignoring all problems with their software because everyone is using them anyway.
I never had a monthly $100 subscription and the company cares this little about their product, it's sad.

darwin911 · 3 months ago

I'm getting these errors non-stop. I can only fix it by either killing the process (need to repeat constantly), or a full machine restart. Using VSCode w/ Claude

posborneao · 3 months ago

are you running docker also? my problem happened when docker was running and the fix was to set network MTU to 1492 instead of 1500. no issues for several weeks now

myongwha · 3 months ago

I had exactly the same issue, but after disabling IPv6 and switching to IPv4, it started working without any problems.

Kupferfox · 3 months ago

same issue here. Windows 11, latest Versions and Updates applied, either CLI or VSCode Extension

jpackagejasonc · 2 months ago

Claude Code — Persistent ECONNRESET Bug Report

Report date: 2026-05-09
Severity: High — most sessions are disrupted, many fail entirely after 11 retry attempts
Working directory of reproduction: /Users/jasonc/tmp/econnreset

debug log

---

1. Executive summary

Claude Code's CLI repeatedly fails with ECONNRESET when calling
https://api.anthropic.com/v1/messages?beta=true and the OTEL/1P telemetry
endpoints. The user experiences this as: most chats fail outright, occasional
ones succeed, and even successful sessions are punctuated by long retry-backoff
stalls.

The critical observation: identical destinations from the same host using
curl/ping/traceroute are fast and 100% reliable (4–6 ms RTT, no packet
loss, TLS handshake ~15–20 ms, HTTP/2 negotiates cleanly). The failures only
occur from inside Claude Code's Bun-bundled runtime. The internal error string
"The socket connection was closed unexpectedly. For more information, pass
verbose: true in the second argument to fetch()"
— is a Bun fetch–specific
error message
. This strongly suggests a client-side issue in the Bun runtime
embedded in the Claude Code binary (or its interaction with this user's
network/TLS path), not generic network reachability.

Headline numbers (last ~30 days):

| Metric | Value |
| --- | --- |
| Total ECONNRESET events logged across sessions | 887 |
| Distinct sessions impacted | 41 |
| Distribution across retries 1–10 | Steady decay (138, 135, 111, 93, 78, 67, 57, 50, 46, 45) — many requests exhaust the full retry budget |
| Sessions ended without ever getting a response | Multiple (per /insights summary, ~5 of 39 analyzed) |
| Curl direct test against api.anthropic.com | 5/5 successful, ~20 ms total |

---

2. Environment

2.1 Host / OS

| Field | Value |
| --- | --- |
| Hardware | Apple Silicon (arm64) MacBook |
| OS | macOS 26.4.1 (build 25E253) |
| Kernel | Darwin 25.4.0 (xnu-12377.101.15~1/RELEASE_ARM64_T8140) |
| Shell | /bin/zsh |
| Hostname | Jasons-MacBook.local |

2.2 Claude Code

| Field | Value |
| --- | --- |
| Version | 2.1.126 |
| Install method | Homebrew Cask (/opt/homebrew/Caskroom/claude-code/2.1.126/) |
| Binary type | Mach-O 64-bit executable arm64 (single-file Bun-bundled binary, 216 MB) |
| Runtime hint (from stack traces) | Bun (/$bunfs/root/src/entrypoints/cli.js, native:7:39) |
| Entrypoint | cli (CLAUDE_CODE_ENTRYPOINT=cli, AI_AGENT=claude-code/2.1.126/agent) |
| Auto-update channel | stable |
| numStartups | 138 |
| MCP servers configured | none (mcpServers: {}) |
| Hooks configured | 0 hooks loaded |
| Plugins | 0 enabled |
| Custom skills/agents | none in ~/.claude/{skills,agents,commands} (all ENOENT) |
| Telemetry | CLAUDE_CODE_ENABLE_TELEMETRY unset (3P telemetry disabled), but 1P event logging is still attempting export and also hitting ECONNRESET |

~/.claude/settings.json:

{
  "statusLine": { "type": "command", "command": "/Users/jasonc/bin/statusline.sh" },
  "effortLevel": "medium",
  "autoUpdatesChannel": "stable",
  "theme": "auto",
  "model": "opus"
}

2.3 Network

| Field | Value |
| --- | --- |
| ISP / upstream | CenturyLink/Lumen (DSL via hlrn.qwest.net) |
| Local LAN | en0, 192.168.0.76/24, MTU 1500 |
| DNS resolvers | 192.168.0.1 (modem), 205.171.2.65 (Qwest/Lumen) |
| api.anthropic.com resolves to | 160.79.104.10 |
| Path to API | LAN → modem → Qwest → Lumen Denver edge → Cloudflare (172.68.32.x) → Anthropic (160.79.104.10); 8 hops, ~5 ms |
| Application Firewall | Disabled (State = 0) |
| HTTP(S) proxy env vars | None set |
| ANTHROPIC_CUSTOM_HEADERS | Not present |

2.4 VPN / virtual interfaces (potentially relevant)

gif0   POINTOPOINT,MULTICAST              mtu 1280
utun0  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 1380
utun1  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 2000
utun2  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 1000
utun3  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 1500
utun4  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 1380
utun5  UP,POINTOPOINT,RUNNING,MULTICAST   mtu 1380

There are six active utun tunnels with assorted MTUs (1000, 1280, 1380,
1500, 2000). scutil --nwi reports en0 is the only IPv4 routable interface
and IPv6 is "No IPv6 states found", so traffic should egress on en0 (MTU
1500). However the mtu 1000 and mtu 1380 tunnels are typical of corporate
VPN clients (Cisco AnyConnect / Cloudflare WARP / Tailscale / GlobalProtect),
and curl --http2 succeeds while Bun's HTTP/2 client does not — worth
investigating an interaction.

---

3. Reproducibility evidence

3.1 Direct connectivity to api.anthropic.com is healthy

$ ping -c 3 api.anthropic.com
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 4.948/5.743/6.234/0.567 ms
$ for i in 1 2 3 4 5; do
    curl -sS -o /dev/null -w "attempt $i: dns=%{time_namelookup}s connect=%{time_connect}s tls=%{time_appconnect}s total=%{time_total}s\n" \
      https://api.anthropic.com/ --max-time 15
  done
attempt 1: dns=0.002281s connect=0.007707s tls=0.016204s total=0.022765s
attempt 2: dns=0.001943s connect=0.007223s tls=0.015215s total=0.022917s
attempt 3: dns=0.002077s connect=0.007390s tls=0.014193s total=0.021565s
attempt 4: dns=0.001982s connect=0.007928s tls=0.015417s total=0.022866s
attempt 5: dns=0.001579s connect=0.006885s tls=0.014775s total=0.023105s

# HTTP/2 also clean
h2 attempt 1: http=404 total=0.021094s http_version=2
h2 attempt 2: http=404 total=0.024482s http_version=2
h2 attempt 3: http=404 total=0.020400s http_version=2

# POST /v1/messages handshake completes (returns 401 because no auth — proves TCP+TLS+HTTP all fine)
http=401 time_total=0.067359s time_connect=0.007025s time_appconnect=0.019567s

traceroute is clean across all 8 hops, no * * * past hop 4.

3.2 Failures inside Claude Code

Source: ~/.claude/debug/latest (current session, 2026-05-09):

2026-05-09T20:34:57.226Z [DEBUG] [API REQUEST] /v1/messages
                              x-client-request-id=f7115f2a-5a9f-4d0f-a7e0-7aa5fb665546
                              source=repl_main_thread
2026-05-09T20:35:00.205Z [DEBUG] Stream started - received first chunk
2026-05-09T20:35:01.549Z [ERROR] [3P telemetry] OTEL diag error:
        Dropped 51 events: max attempts (8) reached
2026-05-09T20:35:02.132Z [DEBUG] [API REQUEST] /v1/messages
                              x-client-request-id=b4778bf6-1518-44cb-a7e4-ac6fafed00ee
                              source=generate_session_title
2026-05-09T20:35:02.151Z [ERROR] API error (attempt 9/11): undefined Connection error.

Note: the model request did receive its first chunk before being interrupted
— failures are happening mid-stream, not at connect time. Sub-requests
(source=generate_session_title) and 1P/3P event exporters fail in the same
interval.

A typical exhausted-retry burst (eleven attempts back-to-back, none succeed,
final x-client-request-id left for server-log lookup):

20:29:51 attempt 1/11: undefined Connection error
20:29:52 attempt 2/11
20:29:53 attempt 3/11
20:29:55 attempt 4/11
20:30:00 attempt 5/11
20:30:09 attempt 6/11
20:30:27 attempt 7/11
20:31:01 attempt 8/11
20:31:39 attempt 9/11
20:32:17 attempt 10/11
20:32:54 attempt 11/11
20:32:54 [ERROR] API error x-client-request-id=6027a507-9112-425e-a26f-27c5fa0292e9
                  (give this to the API team for server-log lookup)

3.3 Canonical error object (from session JSONL)

{
  "type": "system",
  "subtype": "api_error",
  "level": "error",
  "cause": {
    "code": "ECONNRESET",
    "path": "https://api.anthropic.com/v1/messages?beta=true",
    "errno": 0
  },
  "error": {
    "type": null,
    "cause": {
      "code": "ECONNRESET",
      "path": "https://api.anthropic.com/v1/messages?beta=true",
      "errno": 0
    }
  },
  "retryInMs": 587.876,
  "retryAttempt": 1,
  "maxRetries": 10,
  "version": "2.1.119",
  "sessionId": "ec24780a-7579-4c77-b13c-e89f43dc11c9"
}

The exponential-backoff jitter ladder observed: ~512ms → ~1040ms → ~2020ms →
~4530ms → …
(consistent with 2^n + jitter), running to attempt 10/10.

3.4 Telemetry / 1P event logger errors (same root cause, different endpoint)

[ERROR] 1P event logging: 40 events failed to export
        (code=ECONNRESET,
         The socket connection was closed unexpectedly.
         For more information, pass `verbose: true` in the second argument to fetch())

[ERROR] [3P telemetry] OTEL diag error:
        Failed to export 46 events (code=ECONNRESET, ...)
   stack:
        at doExport (/$bunfs/root/src/entrypoints/cli.js:429:1668)
        at processTicksAndRejections (native:7:39)

The phrase pass verbose: true in the second argument to fetch() is Bun's
fetch error format
. This confirms the failures are originating in the Bun
runtime's HTTP client.

---

4. Important x-client-request-ids for server-side correlation

These are exhausted-retry final IDs the CLI itself flagged as
"give this to the API team for server-log lookup":

  • a8a4b32a-6ed4-42b0-98f0-875a1296456d — 2026-05-09T20:32:48Z
  • 6027a507-9112-425e-a26f-27c5fa0292e9 — 2026-05-09T20:32:54Z
  • f7115f2a-5a9f-4d0f-a7e0-7aa5fb665546 — 2026-05-09T20:34:57Z (source=repl_main_thread)
  • b4778bf6-1518-44cb-a7e4-ac6fafed00ee — 2026-05-09T20:35:02Z (source=generate_session_title)
  • e9b03d4e-25d9-4016-b601-55191716c469 — 2026-05-09T20:30:00Z (source=generate_session_title)
  • 25c442f3-3d3b-4920-9ec8-f59a31e6ce98 — 2026-05-09T20:30:27Z (source=generate_session_title)

Many additional IDs are available in
~/.claude/debug/7cf0798e-0996-4915-b21c-f3b501fa6d3f.txt and the per-session
JSONLs under ~/.claude/projects/.

---

5. Temporal pattern

ECONNRESET events are not uniformly distributed; they cluster around active
sessions. Top hours (UTC):

2026-05-04 20:00 →  31
2026-05-06 02:00 →  33
2026-05-06 19:00 →  54
2026-05-07 03:00 →  69
2026-05-07 04:00 → 104
2026-05-07 20:00 →  58
2026-05-08 01:00 →  54
2026-05-08 05:00 →  41
2026-05-09 19:00 →  34
2026-05-09 20:00 → 119

This rules out a single short Anthropic-side outage and suggests a
chronic condition triggered by the user's environment + client behaviour,
not a one-off backend incident. Once a session enters the failing state it
tends to fail across many minutes.

---

6. Hypotheses ranked by evidence

6.1 (Most likely) Bun fetch / HTTP-2 client + middlebox interaction

  • The error string is the Bun-specific fetch failure message.
  • Stack frames trace into the Bun runtime (native:7:39,

/$bunfs/root/src/entrypoints/cli.js).

  • curl to the same host, including --http2, is bulletproof from this

machine.

  • Failures occur after Stream started - received first chunk, i.e. during

long-lived streaming response bodies — exactly the surface area where Bun's
HTTP/2 stream handling has historically had reset bugs.

  • Multiple utun tunnels with non-1500 MTUs are present; if Bun's HTTP/2

implementation differs from libcurl's in how it handles PMTU / window
updates / keepalive over a connection that briefly egresses through one of
these tunnels, that would manifest exactly like this.

Suggested investigation: which exact Bun version is bundled in 2.1.126?
Are there known issues in Bun's HTTP/2 client around streaming RST_STREAM /
GOAWAY handling that match this signature? Can the CLI fall back to HTTP/1.1
for /v1/messages as a workaround?

6.2 Cloudflare edge in front of api.anthropic.com resetting long-idle / mid-stream connections

Hops 7 (172.68.32.12 / 172.68.32.28) are Cloudflare. Cloudflare edges have
been observed to send RST to clients that violate their HTTP/2 keepalive
ping cadence or frame-size expectations. Worth checking server-side whether
these x-client-request-ids show a cf- reset reason or upstream cancel.

6.3 Bundled-binary CA / mTLS path interaction

Debug log shows:

[init] configureGlobalMTLS starting
mTLS: Creating HTTPS agent with custom certificates
CA certs: stores=bundled,system, extraCertsPath=undefined
CA certs: Loaded 145 bundled root certificates
CA certs: system store returned empty

system store returned empty on macOS 26.4.1 is suspicious — usually macOS's
keychain contributes additional roots. If the bundled mTLS agent is
re-handshaking unnecessarily or rotating sockets, that could explain the
mid-stream resets. Probably a secondary factor at most, but worth confirming.

6.4 (Lower likelihood) ISP / DSL pacing

CenturyLink/Lumen DSL with a consumer modem (192.168.0.1) can RST long-lived
TCP flows under load. But: curl long polls don't see this, and the resets
are reproducible during very short request windows, so the ISP angle is
unlikely to be primary.

---

7. What I (the user) have already verified

  • ping, traceroute, curl, and curl --http2 to api.anthropic.com all

succeed reliably and quickly.

  • ✅ No HTTP(S) proxy environment variables.
  • ✅ macOS Application Firewall is off.
  • ✅ No third-party MCP servers, plugins, or hooks active.
  • ✅ Settings file is minimal (statusline + theme + model).
  • ✅ No custom CA certs or extraCertsPath.
  • ✅ Issue reproduces across multiple project directories (~/.claude/projects/

shows 41 distinct session IDs hitting it across git/kina, git/beads,
tmp/urface, git/taljazzco/..., tmp/econnreset, etc.).

  • ✅ Issue spans CLI versions 2.1.119 and 2.1.126, so not a single-build

regression that has since been fixed.

---

8. What would help Anthropic root-cause this

  1. Server-side correlation of the x-client-request-ids in §4 — was the

stream cancelled by the API, by Cloudflare, or by the client? What does the
cf-ray / disconnect-reason header show?

  1. Bun version + HTTP/2 implementation notes for CLI 2.1.126: are there

known Bun fetch-streaming reset issues? Is a fall-back to HTTP/1.1 viable?

  1. A CLAUDE_CODE_FORCE_HTTP1 (or equivalent) env-var workaround so users

on networks where Bun-h2 misbehaves can keep working while a fix lands.

  1. A --verbose-fetch flag that turns on Bun fetch's verbose: true (the

error message itself recommends this) — currently there is no user-facing
way to enable it.

  1. A CLAUDE_CODE_DISABLE_TELEMETRY_EXPORT=1 that fully suppresses 1P

event-logging POSTs as well, since those exporters are also failing and
adding noise to the logs.

---

9. Artefact bundle (paths on this machine)

If the API team needs the raw evidence:

  • ~/.claude/debug/latest → symlink to current debug log

(7cf0798e-0996-4915-b21c-f3b501fa6d3f.txt, ~107 KB).

  • ~/.claude/debug/*.txt → 8 prior debug logs from 2026-05-06 → 2026-05-09.
  • ~/.claude/projects/*/[uuid].jsonl → per-session conversation logs;

every line with "subtype":"api_error" is an ECONNRESET event with full
metadata (timestamp, sessionId, retryAttempt, retryInMs, version, cwd,
gitBranch).

  • 41 affected session UUIDs can be enumerated with:

``
grep -rh ECONNRESET ~/.claude/projects \
| grep -oE '"sessionId":"[^"]+"' | sort -u
``

  • ~/.claude.json → CLI state file (cached GrowthBook flags, startup history).

I am happy to share any of these directly with Anthropic Support on request.

---

10. Impact on me as a user

Per the /insights summary the CLI itself produced on 2026-05-07:

"API connection failures blocking work — ECONNRESET errors repeatedly prevent Claude from responding, sometimes ending sessions before you accomplish anything … Multiple sessions ended with no response at all (jq parsing question, Cargo.toml versions question, simple 'hi' greeting), wasting your time entirely." "Roughly 1 in 5 of your analyzed sessions hit an API connection error mid-flow."

That matches my lived experience: 887 ECONNRESETs across 41 sessions in ~30
days, with several sessions producing zero successful responses despite
exhausting the full 10–11-attempt retry ladder. This makes Claude Code
effectively unusable for sustained work in my environment, which is
particularly frustrating given that every other HTTPS client on the same
machine talks to api.anthropic.com without issue.

brunos3d · 1 month ago

Root cause found — links to the IPv6 and Docker observations in this thread

Posting findings from a deep investigation on Linux (#60133) that explains several comments in this thread.

Root cause: Bun does not set SO_KEEPALIVE

The claude binary bundles Bun 1.3.14 as its runtime. Bun's fetch() does not set SO_KEEPALIVE on TCP sockets. Without it, idle connections (during tool execution gaps in agentic sessions) are silently dropped. Confirmed live:

ss -tnop state established '( dport = :443 )'

chrome → 34.194.3.76:443  timer:(keepalive,16sec,0)  ← SO_KEEPALIVE ON
claude → 160.79.104.10:443 (no timer)                ← SO_KEEPALIVE NOT SET

Why "disabling IPv6 fixed it" (@myongwha)

api.anthropic.com resolves to IPv6 first via getaddrinfo. Bun uses the first result, so it connects over IPv6 by default. IPv6 routing through home routers tends to have shorter stateful firewall timeouts than IPv4 NAT, making idle connections more likely to be dropped. Forcing IPv4 via NODE_OPTIONS="--dns-result-order=ipv4first" has the same effect as disabling IPv6 system-wide, without the side effects.

Why "setting Docker MTU to 1492 fixed it" (@posborneao)

Docker bridges lower the effective path MTU, which can cause TCP segment fragmentation on IPv6 paths. With fragmented packets, TCP keepalive probes (from other apps) may not reach the server cleanly — but since claude sends no keepalive probes at all, the MTU change incidentally affects routing path selection in a way that changes which connections get dropped first.

Workaround

# Add to ~/.zshrc
export CLAUDE_CODE_REMOTE_SEND_KEEPALIVES=true
export BUN_CONFIG_HTTP_IDLE_TIMEOUT=300
export BUN_CONFIG_HTTP_RETRY_COUNT=3
export NODE_OPTIONS="--dns-result-order=ipv4first"

For a complete OS-level fix that forces SO_KEEPALIVE on all claude sockets:

cat > /tmp/ka.c << 'CSRC'
#define _GNU_SOURCE
#include <stddef.h>
#include <sys/socket.h>
#include <dlfcn.h>
int socket(int domain, int type, int protocol) {
    static int (*orig)(int,int,int);
    if (!orig) orig = dlsym(RTLD_NEXT, "socket");
    int fd = orig(domain, type, protocol);
    if (fd >= 0 && (type & 0xf) == SOCK_STREAM) {
        int v = 1; setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &v, sizeof(v));
    }
    return fd;
}
CSRC
mkdir -p ~/.local/lib
gcc -shared -fPIC -O2 -o ~/.local/lib/libkeepalive.so /tmp/ka.c -ldl
echo 'export LD_PRELOAD="$HOME/.local/lib/libkeepalive.so${LD_PRELOAD:+:$LD_PRELOAD}"' >> ~/.zshrc
sudo sysctl -w net.ipv4.tcp_keepalive_time=60

Full investigation with binary analysis, ss output comparisons, and feature flag dump: #60133

jpackagejasonc · 1 month ago

the workaround envvars do not seem to offer any improvement for me

brunos3d · 1 month ago
the workaround envvars do not seem to offer any improvement for me

Its because it's an Anthropic's API issue. And idk, but I suspect it's intentional for PRO users' accounts only.

jpackagejasonc · 1 month ago

it's so genuinely unusable that I've given up and canceled my pro subscription

brunos3d · 1 month ago

@jpackagejasonc definitely, same from here. This one was from today's interaction.

<img width="1368" height="446" alt="Image" src="https://github.com/user-attachments/assets/e97d6339-97fa-4e3d-ad8b-4cf6506eea37" />

I hope more people start posting about this issue here so that Anthropic begins working on a solution for these annoying errors. I’m genuinely considering canceling my subscription.

olivierrubinger · 1 month ago

Claude CLI is basically unusable for me right now until this gets fixed. What’s interesting is that the issue only seems to happen on my machine/account as my coworkers are able to use the API normally. I hope they get rid of the error soon... What Im doing to avoid the error is starting new sessions everytime I finish a task, it seems like a temporary fix, but even though it crashes 2 to 3 times per session while doing this.

jpackagejasonc · 1 month ago

Root cause found for persistent ECONNRESET: MTU blackhole (path drops full-size frames, PMTUD broken)

TL;DR: Months of Unable to connect to API (ECONNRESET) on every request turned out to be a network-path MTU problem, not Claude Code, not my account, and not anything in ~/.claude. The path between my machine and the internet silently drops full-size (1500-byte) packets and never sends the ICMP "fragmentation needed" signal back, so PMTU discovery is blacked out. Small requests succeed; any request with a large body — i.e., every real Claude Code request — gets reset within one RTT. Clamping interface MTU to 1400 fixed it instantly.

If you're in this thread with "all diagnostics pass but Claude Code can't connect," try the 5-minute test below before anything else.

Environment

  • Claude Code 2.1.173, macOS, residential fiber, Wi-Fi
  • Failure mode: every prompt → Retrying in Xs · attempt Y/10 → ~3 minutes → Unable to connect to API (ECONNRESET)
  • Persisted for ~3 months across CLI versions, rm -rf ~/.claude, clean reinstalls, /logout//login, and two different accounts (CLAUDE_CONFIG_DIR isolated). A second machine on the same LAN worked fine, which made it look like an account/edge problem. It wasn't.

Why every standard diagnostic passed

All the usual checks use small packets, so they can't see this failure:

  • curl -I https://api.anthropic.com → fine
  • curl GET /v1/models over both IPv4 and IPv6 → HTTP 401 (transport fine)
  • DNS, TCP 443, TLS handshake, HTTP/2 → all fine
  • systemextensionsctl list → 0 extensions; pfctl -sr → stock Apple rules
  • claude.ai in the browser → fine (small/interactive payloads, graceful fallback)

Meanwhile in claude --debug logs:

  • A small POST to /v1/messages (the CLI's API-key verification probe) succeeded — real HTTP 400 from the API with a request_id, ~170 ms
  • Every full-size /v1/messages request (system prompt + context = hundreds of KB) went from [API REQUEST] to API error (attempt N/11): undefined Connection error. in 25–40 ms — an active reset on the first large write, not a timeout
  • Telemetry exports to a different endpoint also failed with ECONNRESET continuously → not host-specific, not auth-specific

Pattern: payload-size-dependent connection kill.

The 5-minute test (no Claude software involved)

# 1. Small POST — should return 401 (transport works)
curl -sS -o /dev/null -w "small: %{http_code}%{errormsg}\n" \
  -X POST https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" -d '{"t":1}'

# 2. ~200KB POST — the size class of a real Claude Code request
python3 -c "print('{\"pad\":\"' + 'x'*200000 + '\"}')" > /tmp/big.json
curl -sS -o /dev/null -w "large: %{http_code}%{errormsg}\n" \
  -X POST https://api.anthropic.com/v1/messages \
  -H "content-type: application/json" --data @/tmp/big.json

My result:

small: 401
large: 000  curl: (56) Recv failure: Connection reset by peer

If the large POST resets where the small one passes, confirm with a ping ladder (don't-fragment full-size frames):

ping -c 5 -q -D -s 1472 api.anthropic.com   # 1500-byte frames
ping -c 5 -q -D -s 1372 api.anthropic.com   # 1400-byte frames

My result: 66% loss at 1472, 0% loss at 1372 and below. Clean size cliff = MTU blackhole (likely tunnel/PPPoE-style encapsulation upstream eating header bytes, with ICMP frag-needed filtered somewhere).

The fix

# macOS — immediate, per-machine
networksetup -setMTU Wi-Fi 1400      # use your service name from -listallnetworkservices

Large curl POST immediately returned 401, and Claude Code connected on the next run. Permanent fix is at the router: set WAN MTU appropriately / enable MSS clamping so every device is covered. (Revert the Mac with networksetup -setMTU Wi-Fi 1500 once the router is fixed.) Worth a ticket to your ISP too — dropping 1500-byte frames while blackholing PMTUD is broken on their side.

Why one machine on the same LAN worked and another didn't: different link/negotiation between the two devices — "same network" does not mean same effective path MTU behavior, and only a tool that sends sustained large upstream payloads (like an LLM CLI shipping full context on every request) reliably trips it.

Suggestion for the Claude Code team

API error (attempt N/11): undefined Connection error. carries zero diagnostic signal for this entire failure class. Two cheap improvements would have saved me three months:

  1. Surface bytes-written-before-reset (or even just "connection reset during request body upload") instead of undefined Connection error.
  2. When all retries fail with resets and a small probe to the same host succeeds, print a hint: "Large requests are being reset while small requests succeed — check path MTU (see docs)." The CLI already makes small requests (key verification, settings fetch) whose success right before large-request failure is exactly this signature.

Hope this unblocks someone else in this thread.