[BUG] After a Wi-Fi drop, ECONNRESET persists even once the network is back — only a full reboot recovers

Status Open
Reported on v2.1.251
Maintainer reply None cached
Activity 0 comments · opened Aug 25, 2026

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?

Claude Code works for long periods as long as the process never hits a path/address-family failure. After that it stays dead even though the machine has a working internet connection.

Two triggers, same sticky failure:

A. Wi-Fi drop → restore (original). Session healthy → Wi-Fi actually drops (sleep, signal loss, router blip) → Wi-Fi comes back. Browser, ping, and curl -4 https://api.anthropic.com succeed. The already running Claude Code process does not recover. Every subsequent API request fails with ECONNRESET (sometimes later mislabeled ConnectionRefused). Retries exhaust 10/10. Full Quit + relaunch 2–3 times tonight still failed; a reboot is the only thing that has been fully reliable. Idle Wi-Fi with no disconnect does not reproduce this.

B. IPv6 disabled on the interface, AAAA still in DNS (tonight, 2026-08-30). Wi-Fi IPv6 is Off (scutil --nwi: no IPv6 state). Public DNS still returns 2607:6bc0::10 and 160.79.104.10. curl -4 to api.anthropic.com returns 404 in ~0.23s (unauthenticated root = reachable). curl -6 fails in 2ms; nc to the AAAA is No route to host. Claude Code in the same second shows Connection dropped (ECONNRESET) then Connection refused — a firewall or proxy may be blocking it. There is no proxy and Application Firewall is disabled. That TUI string is a misdiagnosis.

The distinctive part vs other ECONNRESET reports: the OS path is healthy (control below), the client stays stuck, retries do not open a working IPv4 connection, and changelog lines that already claimed “retry ECONNRESET” / “fresh TCP on retry” do not cover this on 2.1.251.

This will not reproduce on Anthropic office dual-stack Wi-Fi where curl -6 https://api.anthropic.com succeeds. “Could not reproduce on our network” without the control below is not a result for this bug. See #82509: a different code path was tested, needs-repro was applied, github-actions closed it.

The network that exposes this (and why that still is a product bug). I know this blows up on our office Wi-Fi, not on a simple/flat home LAN with a clean session. That office path is nested NAT: client → office Wi-Fi router (still in router mode) → another router → ISP CPE / CGNAT. Other programs on the same Wi-Fi keep working (browser, curl, the rest of the machine) — at least well enough to work. Claude Code does not. A paid Claude Code / Anthropic subscription is then unusable “from the word completely.” This has been going on for about a year. It used to be roughly once a month and then disappear; it is now frequent enough that I cannot actually use the product.

That topology can explain why the sockets die (NAT timeouts, path changes, CGNAT). It does not explain why only this client stays dead after curl -4 https://api.anthropic.com is already 404.

Do not close this as “use Cloudflare WARP / a VPN / a VPS.” WARP has historically hidden the bug on this same office Wi-Fi (session survived association drops). That is diagnostic, not a fix. Turning WARP on for the whole machine is not an acceptable product workaround: throughput drops from ~800 Mbps to ~100 Mbps (≈70–80% lost), and every normal site (YouTube and the rest) starts serving shared-egress CAPTCHAs because the public IP is a Cloudflare pool, not mine. I will not run a third-party VPN all day, burn most of the link, and click robot checks, in order to use a subscription I already pay for. A local Docker container on this laptop would use the same nested-NAT path and would not change the bug. Renting a VPS just to run claude is the same class of unpaid ops tax. If the official position is “your router,” the product still has to survive the same network every other app on the laptop already survives.

Related but not the same:

  • #23744 / #23081 — stale HTTP/2 pool after network change; those describe process restart helping. Here even Quit×2–3 was not enough tonight.
  • #75956, #87424, #86866, #89060 — ECONNRESET on macOS / home last-mile; they do not include the curl-vs-Claude control or the IPv6-off + AAAA trap.
  • #84194 — Bun client fails, Node/curl succeed (Windows). Same split: this client is Bun, not Node.
  • #37081 / #60133 — NODE_OPTIONS ignored by the embedded runtime.

What Should Happen?

  • Detect interface / default-route / address-family change, or treat ECONNRESET / connect failure after a drop as a dead pool.
  • Evict keep-alive / HTTP/2 sockets. Next retry must be a new TCP connection.
  • If the OS has no IPv6 route, do not pin the process to AAAA. Fall back to A and keep using A.
  • Do not surface “firewall or proxy may be blocking it” when there is no proxy and no firewall and curl -4 to the same host succeeds.
  • Resume the session without requiring a process restart, and certainly without a machine reboot.

Transient errors during the outage are expected. Sticky errors after the link is back, or while IPv4 HTTPS already works, are not.

Error Messages/Logs

Connection dropped (ECONNRESET) · Retrying in 4s · attempt 5/10
Connection refused — a firewall or proxy may be blocking it (ConnectionRefused) · Retrying · attempt 6/10
API Error: Unable to connect to API (ECONNRESET)
API Error: Connection dropped (ECONNRESET)

Observed in one process, minutes apart, while the control (below) stayed green. Retries exhaust the budget. Further prompts in the same process keep failing.

Mandatory control (run in a second terminal WHILE Claude is on Retrying N/10)

If this output is not in the investigation, the bug was not reproduced.

date
curl -4 -sS -m 8 -o /dev/null -w 'ipv4 %{http_code} %{time_total}s\n' https://api.anthropic.com/
curl -6 -sS -m 4 -o /dev/null -w 'ipv6 %{http_code} %{errormsg}\n' https://api.anthropic.com/ || true
dscacheutil -q host -a name api.anthropic.com
scutil --nwi
networksetup -getinfo "Wi-Fi" | grep -i ipv6
scutil --proxy
/usr/libexec/ApplicationFirewall/socketfilterfw --getglobalstate

Captured 2026-08-30 ~22:29 local (UTC+5) during a failing 2.1.251 CLI session:

ipv4 404 0.23s
ipv6 Failed to connect to api.anthropic.com port 443 after 2 ms
dscacheutil:
  ipv6_address: 2607:6bc0::10
  ip_address: 160.79.104.10
nc 2607:6bc0::10 443 → No route to host
nc 160.79.104.10 443 → succeeded
scutil --nwi: IPv4 en0 Reachable; No IPv6 states found
Wi-Fi IPv6: Off
proxy: none (web/secure/SOCKS/PAC Off)
Application Firewall: disabled

404 on the unauthenticated API root means TLS+HTTP to Anthropic succeeded. Claude Code still retrying is the bug.

Steps to Reproduce

Office dual-stack Ethernet + a 20-token “hello” will not hit this. Required:

  1. networksetup -setv6off Wi-Fi (or any interface with no IPv6 default route). Confirm scutil --nwi has no IPv6 state.
  2. Confirm DNS still serves AAAA for api.anthropic.com (dscacheutil as above). This is default 1.1.1.1 / 8.8.8.8 behavior; you do not need a broken resolver.
  3. Start claude 2.1.251 (~/.local/bin/claude). Confirm one short prompt completes.
  4. Send a long streaming turn (image attach and/or Opus 1M / long tool loop). Short completions often survive; this is the request that dies.
  5. Optional original trigger: drop Wi-Fi (networksetup -setairportpower en0 off ~10s, then on). Wait until curl -4 https://api.anthropic.com is 404 again. Send another prompt in the same process.
  6. Observe 10/10 retries. In a second terminal, re-run the control. If ipv4 is 404 and Claude is still ECONNRESET/ConnectionRefused, this issue is reproduced.

Does not count as a repro attempt

  • Dual-stack office Wi-Fi where curl -6 https://api.anthropic.com succeeds.
  • A flat home LAN / mobile hotspot / Cloudflare WARP / datacenter VPS path (those hide the bug). WARP in particular is not a recommended workaround: it costs most of the user’s bandwidth and puts them on a shared anycast IP that trips bot checks. Local Docker on the same laptop is the same last mile and is not a test of a fix.
  • Testing only after a full reboot with a short prompt.
  • Treating Desktop Code tab 2.1.247 (~/Library/Application Support/Claude/claude-code/2.1.247/claude.app) and CLI 2.1.251 as one binary. They are not.
  • Citing changelog “we now retry ECONNRESET” / “fresh TCP on retry” without showing a new connection in the failing process.
  • Asking the reporter to set NODE_OPTIONS=--dns-result-order=ipv4first. It is already set in ~/.claude/settings.json env. Bun ignores it (#37081). BUN_CONFIG_DISABLE_HTTP2=1 was also set; the 2.1.251 session still failed on the long stream.
  • Closing as “restart the process” (#23744). Tonight full Quit ×2–3 did not recover.

Claude Model

Not sure / Multiple models (reproduced on Opus 5 1M streaming with an image attach; also on shorter turns after a Wi-Fi drop)

Is this a regression?

I don't know. Changelog already claimed fixes for this class; 2.1.251 still fails.

Last Working Version

Claude Code Version

2.1.251 (CLI); Desktop Code tab separately at 2.1.247. Originally filed on 2.1.245.

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

iTerm2 / Terminal.app (claude CLI) and Claude.app Code tab (different binary)

Additional Information

Environment

  • macOS 26.6.2 (build 25G83) / Darwin 25.6.0, Apple Silicon (arm64)
  • Claude Code CLI 2.1.251 native install ~/.local/bin/claude (runtime is Bun, not Node; system Node v26 is unused for this)
  • Home IPv4 via consumer Wi-Fi (typical 192.168.0.0/24 → NAT → CGNAT-class last mile). No HTTP/HTTPS/SOCKS proxy.
  • Several utun* interfaces exist (normal current macOS). They are not the default route (netstat -rn default is en0 → gateway). Do not close this as “VPN”.
  • NODE_OPTIONS=--dns-result-order=ipv4first and BUN_CONFIG_DISABLE_HTTP2=1 in user settings.json env did not stop the failure.

What this is not

  • Not “no internet.” The control curl runs during the failure.
  • Not a local firewall or proxy. Both off; TUI still blames them on ConnectionRefused.
  • Not random noise on a stable association. Trigger A needs a real disconnect; trigger B needs IPv6-off + AAAA still published (default).
  • Not “the whole internet is down.” Same SSID: browser and curl stay usable; Claude Code does not. Nested NAT/CGNAT is the environment, not a license to ignore a client that never reconnects.
  • Not fixed by the already-shipped retry/backoff/fresh-TCP changelog entries: 10 retries still RST / refuse on a live IPv4 path.
  • Not fixed by telling the user to run WARP, a VPN, or a VPS. WARP on this office Wi-Fi historically kept the session alive across Wi-Fi drops — which only proves Anthropic is reachable when the last mile is a stable tunnel. It is not a fix: ~70–80% throughput loss plus shared-IP CAPTCHAs on ordinary sites. I am not going to pay for Claude Code and then also pay in bandwidth, CAPTCHAs, or a rented VM so the Bun client can keep a socket. The client on the raw nested-NAT path is what has to recover.

Falsifiable client bugs

  1. Address family: no IPv6 route, process still uses 2607:6bc0::10, instant fail, no sticky failover to A for the rest of the process.
  2. Stale pool: after Wi-Fi drop/restore (or network-service churn), keep-alive/HTTP2 sockets reused; all retries hit the dead connection. “Fresh TCP on retry” is not happening here.
  3. Wrong error copy: ConnectionRefused + “firewall or proxy” when curl -4 to the same host works.

Ask of whoever picks this up

Paste the control-block output captured during a failing retry from a machine with IPv6 off and AAAA still in DNS. If that output is missing, this bug was not reproduced. “Could not reproduce on our Wi-Fi” is not a result for this report.

View original on GitHub ↗