[BUG] All models fail with ConnectionRefused while the same OAuth token reaches the API (macOS, 2.1.219–2.1.220)

Status Open
Reported on v2.1.220
Maintainer reply ✓ Yes — bcherny
Activity 3 comments · opened Jul 31, 2026
💡 Likely answer: A maintainer (bcherny, collaborator) responded on this thread — see the highlighted reply below.

Preflight Checklist

  • [x] I searched existing issues. The closest reports I found are #53346 and #48008, but neither includes the isolation results below.
  • [x] This is a single bug report.
  • [x] I am using the latest Claude Code release.

What's Wrong?

Every first-party /v1/messages request fails almost immediately with a generic Connection error. After all 11 retries, Claude Code reports ConnectionRefused.

This affects both the main inference request and session-title generation. Failing requests do not show an x-client-request-id in the debug log and record api=0ms, suggesting the failure happens before Claude Code receives an API response or starts a stream.

The same OAuth access token is accepted by api.anthropic.com when tested directly with a deliberately incomplete request: the API returns a normal HTTP 400 validation response (model: Field required) and a request ID. This isolates the problem to Claude Code's request/transport path rather than DNS, TLS, basic API reachability, or token validity.

The failure is deterministic right now, but the same Claude Code version successfully streamed a response on the previous day after an earlier period of identical failures.

What Should Happen?

Claude Code should send the authenticated request and either begin streaming or return the actual HTTP/API error. It should not classify a reachable API and accepted OAuth credential as ConnectionRefused.

If a local preflight, request construction, beta/header validation, or transport initialization step fails, the debug log should expose that underlying error instead of the generic connection classification.

Error Messages/Logs

Final retry:

[DEBUG] [API REQUEST] /v1/messages source=repl_main_thread
[ERROR] API error (attempt 11/11): undefined Connection error.
[ERROR] Error in API request: Connection error.
[ERROR] Connection error details: code=ConnectionRefused, message=Unable to connect. Is the computer able to access the url?
[ERROR] API connection_error after retries: Connection error.
[DEBUG] [engine] turn 1 end (turns=1 usage in=0 out=0 cost=$0.0000 api=0ms stop=stop_sequence resultLen=0)

The first attempt typically fails within 1–5 ms:

[DEBUG] [API:timing] dispatching to firstParty model=claude-haiku-4-5-20251001
[DEBUG] [API REQUEST] /v1/messages source=sdk
[ERROR] API error (attempt 1/11): undefined Connection error.

A successful session using the same installed 2.1.220 binary on the previous day logged:

[DEBUG] [API REQUEST] /v1/messages x-client-request-id=<uuid> source=repl_main_thread
[DEBUG] Stream started - received first chunk
[DEBUG] [API:timing] first byte after 1378ms

Isolation / Tests Performed

| Test | Result |
|---|---|
| claude doctor | Native 2.1.220, darwin-arm64, no installation issues found |
| claude auth status | Logged in via claude.ai, provider firstParty, Max subscription |
| OAuth credential metadata | Access token is unexpired and includes user:inference scope |
| Direct unauthenticated POST to https://api.anthropic.com/v1/messages | HTTP 401 as expected |
| Node fetch() to the same endpoint without auth | HTTP 401 as expected |
| Direct POST using the same OAuth access token and {} body | HTTP 400 invalid_request_error: model: Field required; request ID req_011CdZS1XGNn1eAW9gGJum1B |
| TLS verification | Passes; curl ssl_verify_result=0 |
| Proxy-related environment | HTTP_PROXY, HTTPS_PROXY, and NO_PROXY are unset |
| claude --safe-mode -p ... | Same repeated Connection error; rules out hooks, plugins, skills, LSP, and MCP customization |
| --no-session-persistence --tools '' --effort low | Same failure with a minimal client configuration |
| Model: Claude Sonnet 5 | Fails |
| Model: claude-haiku-4-5-20251001 | Fails |
| Native Claude Code 2.1.220 | Fails |
| pnpm dlx @anthropic-ai/claude-code@2.1.220 | Fails |
| pnpm dlx @anthropic-ai/claude-code@2.1.219 | Fails |
| Anthropic status API at test time | All systems operational; zero unresolved incidents |

A socket observation during the failing run showed established TLS connections to Anthropic's edge, while Claude Code still classified each request as ConnectionRefused.

Steps to Reproduce

  1. Sign in with a Claude Max subscription using claude auth login.
  2. Run:
timeout 30 claude \
  --safe-mode \
  --no-session-persistence \
  --model haiku \
  --effort low \
  --tools '' \
  --debug-file /tmp/claude-safe-mode.log \
  -p 'Reply exactly OK.'
  1. Observe that the command eventually prints Execution error.
  2. Inspect /tmp/claude-safe-mode.log.
  3. Each /v1/messages attempt fails immediately with undefined Connection error.
  4. Let all retries complete; the final classification is ConnectionRefused.

Claude Model

Multiple models: Claude Sonnet 5 and Claude Haiku 4.5

Is this a regression?

Intermittent regression. Claude Code 2.1.220 successfully completed requests on 2026-07-30, but the same version fails consistently on 2026-07-31. Version 2.1.219 currently fails as well.

Last Working Version

2.1.220 (worked on the previous day with the same account and machine)

Claude Code Version

2.1.220 (native, commit 4073f59596e2); also reproduced with 2.1.219

Platform

Anthropic API / first-party Claude.ai OAuth

Operating System

macOS 26.5 (Build 25F71), Apple Silicon arm64

Terminal/Shell

Ghostty 1.3.1 / zsh

Additional Information

  • No API key or custom ANTHROPIC_BASE_URL is configured.
  • No proxy environment is configured.
  • The official status page had no active incident during testing.
  • I can provide the full sanitized debug logs privately if needed.
  • Related: #53346 (ConnectionRefused) and #48008 (stream connection failures where curl still succeeds).

View original on GitHub ↗

3 Comments

jdunham2 · 1 month ago

Same issue, with isolation data that may help narrow this down.

Environment: macOS Tahoe 26.3.1, Claude Code 2.1.220 (reproduces in BOTH the desktop app and the npm CLI on Node 22.23.1), subscription auth. No VPN, no proxy, no ANTHROPIC_BASE_URL override, zero third-party network/system extensions.

Timeline: Abrupt onset 2026-07-30 ~19:30 EDT after 9 clean days (per desktop app main.log — first ECONNRESET at 19:32, none before that since log start Jul 21). ~42+ ECONNRESET cycles logged since, continuing well after the Jul 29–31 status-page incidents were marked resolved. Nothing changed locally at onset: CLI 2.1.220 was installed Jul 27, last OS update was Mar 2026.

Isolation results:

  • Not the local network: reproduces identically on home internet and phone hotspot.
  • Not the model: started while using Opus 5, persists after switching to Fable 5 (incl. [1m] variant).
  • Correlates with context size: sessions over ~100k tokens of context (especially ones running subagents) fail repeatedly; fresh/small sessions on the same machine at the same time are unaffected. The worst-affected session runs ~121k input tokens per request.
  • Small requests never fail: while a large session was actively failing, an unauthenticated curl probe to api.anthropic.com/v1/models every 5s went 120/120 with zero failures, and 60-second held TLS connections on both IPv4 (160.79.104.10) and IPv6 (2607:6bc0::10) stayed up cleanly. Only large, long-lived authenticated streaming requests are affected.

Failure detail (from session transcript): retries spaced ~30–60s apart, ~4 min to exhaust all 10 attempts, then the turn dies. Every attempt logs:
code: ECONNRESET, isSSLError: false, isNetworkDown: false — "The socket connection was closed unexpectedly" (Node fetch/undici). Desktop app CycleHealth shows error cycles lengthening (829s → 834s → 1,099s of retrying per turn) before full 10-attempt failures began. Earlier cycles logged as api_error (success) — i.e., recovered after many retries — but we now see complete failures.

Mitigations tried (no effect on root cause): npm CLI instead of native binary, NODE_OPTIONS=--dns-result-order=ipv4first, API_TIMEOUT_MS=600000, CLAUDE_CODE_MAX_RETRIES=15, CLAUDE_CODE_RETRY_WATCHDOG=1, router reboot, network switch. /compact (reducing context size) is the only thing that helps, which is consistent with the size correlation.

Happy to provide fuller logs or run diagnostics on request.

bcherny collaborator · 14 days ago

Thanks for the isolation table — it made this fast to check.

I ran your exact command on 2.1.233 (Linux x64, first-party OAuth) in a clean directory: it completed normally, and the debug log showed x-client-request-id on every /v1/messages line plus Stream started - received first chunk. Not reproduced.

I then forced a genuine TCP refusal by pointing the client at a port nothing was listening on. That reproduced your signature exactly — [API REQUEST] /v1/messages with no x-client-request-id, API error (attempt N/11): undefined Connection error., then code=ConnectionRefused, message=Unable to connect. Is the computer able to access the url?. A host that fails to resolve is reported differently, so ConnectionRefused isn't a generic bucket: it's the actual socket error the OS returned, surfaced as-is. The missing request ID and api=0ms are just what any pre-response connect failure looks like — not a preflight or header step failing.

So the client is reporting truthfully, and something on that machine refused the connection within a few milliseconds. curl succeeding doesn't rule that out — refusals that fast are local, and per-application network filters (endpoint security, VPN split-tunnel rules, content filters) commonly allow curl while refusing a different binary. That also fits the same build working one day and failing the next.

To confirm, could you share: (1) what VPN / endpoint-security / network-filtering software is installed, (2) what api.anthropic.com resolves to at failure time (a loopback or private-range answer would explain it), (3) whether ~/.claude/settings.json or a managed settings file sets a proxy under env — an unset shell environment doesn't cover those, and (4) claude doctor output.

Docs: https://code.claude.com/docs/en/network-config and https://code.claude.com/docs/en/troubleshooting

Also worth upgrading: on 2.1.233 this same failure reads "Connection refused — a firewall or proxy may be blocking it (ConnectionRefused)" instead of a bare execution error.

🤖 Generated with Claude Code

Ray0907 · 13 days ago

Thanks for the detailed response. I found a workaround: deleting the project-local .claude directory made Claude Code connect normally again. After removing it, the same command succeeds. I have not isolated which file or setting inside .claude caused the issue.