Intermittent `socket connection was closed unexpectedly` (ECONNRESET) on startup — ~40-70% failure rate across parallel startup fetches

Resolved 💬 2 comments Opened May 25, 2026 by eduardoforlog Closed Jun 26, 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?

Roughly 40–70% of Claude Code invocations fail at startup with:

API Error: The socket connection was closed unexpectedly.
For more information, pass `verbose: true` in the second argument to fetch()

UI shows "Problema de conexão / Verifique sua conexão". The error is not session-length related — it happens on the first request of an interactive TUI session, and in 40–70% of one-shot claude -p calls when the response is non-trivial (>~30 words).

Observed rates across batches:

  • 1-word response ("hi"): 0/5 fail
  • ~30-word response: 5/15 fail (33%)
  • ~250-word response: 4/10 → 5/10 → 7/10 fail across separate batches (40–70%)

Failure rate scales with response size, which initially suggested content inspection — but multiple tests below rule that out.

Environment

  • Claude Code 2.1.150 (also reproduced on 2.1.149 and 2.1.140)
  • Install: npm install -g @anthropic-ai/claude-code (bundled bun runtime)
  • OS: Windows 11 Enterprise (pt-BR)
  • Node v24.3.0 (per x-stainless-runtime-version in debug log)
  • Account: Claude Max, authenticated
  • Network: wired, no VPN, no corporate proxy (HTTPS_PROXY empty, WinINET ProxyEnable=0)
  • TLS: real cert from Google Trust Services arrives intact (no MITM)

What Should Happen?

Claude Code should successfully establish the HTTPS connection to api.anthropic.com and stream the response without ECONNRESET / socket-close errors. The parallel startup fetches (Bootstrap, MCP registry, claudeai-mcp, /v1/messages) should not race against each other while the mTLS HTTPS agent is being constructed. When a transient ECONNRESET does occur, the configured retry policy (e.g. BUN_CONFIG_HTTP_RETRY_COUNT=3) should be honored before the failure is surfaced to the user.

Error Messages/Logs

See "Steps to Reproduce" above for the complete debug log capture.

Steps to Reproduce

Repro:

# 10x one-shot with a ~250-word response
1..10 | ForEach-Object {
  claude -p "Liste em portugues, em ate 250 palavras, os 10 maiores rios do Brasil com extensao em km e estados que cruzam."
}

Run with claude --debug --debug-to-stderr -p "..."; on failures (about half the runs) the stderr contains:

[DEBUG] [API REQUEST] /v1/messages source=generate_session_title
[DEBUG] [Bootstrap] Fetch failed: ECONNRESET
[ERROR] [Bootstrap] fetchBootstrapData failed: Error: The socket connection was closed unexpectedly.
[ERROR] Failed to fetch MCP registry: The socket connection was closed unexpectedly.
[DEBUG] [claudeai-mcp] Fetch failed (ECONNRESET)
[Anthropic SDK INEo] connection failed - error; no more retries left
[Anthropic SDK DEBUG] connection failed (error; no more retries left) {
  url: "https://api.anthropic.com/v1/messages?beta=true",
  durationMs: 167,
  message: "The socket connection was closed unexpectedly..."
}
[ERROR] API error (attempt 1/11): undefined Connection error.

Key observations from the debug log:

  1. Four parallel endpoints fail simultaneously in ~167msBootstrap, MCP registry, claudeai-mcp, and /v1/messages?beta=true.
  2. mTLS: Creating HTTPS agent with custom certificates is logged 3–4 times within milliseconds on every startup — each request appears to construct its own agent rather than share a pool.
  3. no more retries left is logged even though BUN_CONFIG_HTTP_RETRY_COUNT=3 is set — this code path is not honoring the retry config.
  4. The erroe is ECONNRESET (TCP RST), not a clean FIN or HTTP-level error.
  5. When the request succeeds, cf-ray and server: cloudflare headers confirm the Cloudflare edge.

Pattern is consistent with a race condition in the bun HTTP client when N parallel HTTPS requests are dispatched immediately after constructing the mTLS agent at startup. Some sockets get reset before the TLS handshake fully completes, the per-codepath retry is not triggered, and the failure bubbles up to the user.

Claude Model

None

Is this a regression?

Yes, this worked in a previous version

Last Working Version

_No response_

Claude Code Version

2,1.150

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Terminal.app (macOS)

Additional Information

| Hypothesis | Test | Result |
|---|---|---|
| Corporate proxy / TLS inspection | Checked WinINET, HTTPS_PROXY, npm proxy; inspected real cert chain | Clear — api.anthropic.com cert from Google Trust Services arrives intact |
| Network idle / firewall timeout | 60-second sustained TLS connection from PowerShell | Held without drop |
| IPv6 instability | NODE_OPTIONS=--dns-result-order=ipv4first | No effect |
| HTTP/2 GOAWAY from Cloudflare | BUN_CONFIG_DISABLE_HTTP2=1 | No effect |
| Keep-alive / connection reuse | CLAUDE_CODE_REMOTE_SEND_KEEPALIVES=true, BUN_CONFIG_HTTP_IDLE_TIMEOUT=300, BUN_CONFIG_HTTP_KEEP_ALIVE_TIMEOUT=60, CLAUDE_STREAM_IDLE_TIMEOUT_MS=120000 | No effect on failure rate |
| Corporate EDR/DLP (Microsoft Defender for Endpoint Sense running) | Copied claude.exe to %TEMP%\zzz.exe (different name AND path) and re-ran 10× battery | 5/10 fail (50%) — statistically identical to original. Rules out path/name-based inspection |
| Server-side MCP connector (claude.ai Microsoft 365, status Failed to connect / HTTP 401, never linked by user) | Set tengu_claudeai_mcp_connectors to false in ~/.claude.json | Setting reverts on next startup via cachedGrowthBookFeatures sync. After it briefly stuck (claude mcp list showed "No MCP servers configured"), failure rate went 40% → 70%. Not the cause |
| Regression in 2.1.150 | Downgraded to 2.1.140 | 5/10 fail — same rate. Bug exists in both versions |
| Network-level raw TLS to api.anthropic.com | 30 sequential Invoke-WebRequest HEAD calls + 60-second held SSL stream | 30/30 success — network is fine |

PowerShell's raw .NET TLS client and Invoke-WebRequest never fail. Only the bundled bun runtime fails, and only in the multi-parallel-fetch startup window.

Workarounds tried (all ineffective):

// ~/.claude/settings.json — env block, all active during failing runs
{
  "env": {
    "CLAUDE_CODE_REMOTE_SEND_KEEPALIVES": "true",
    "BUN_CONFIG_HTTP_IDLE_TIMEOUT": "300",
    "BUN_CONFIG_HTTP_RETRY_COUNT": "3",
    "ANTHROPIC_LOG": "debug",
    "NODE_OPTIONS": "--dns-result-order=ipv4first",
    "CLAUDE_STREAM_IDLE_TIMEOUT_MS": "120000",
    "BUN_CONFIG_DISABLE_HTTP2": "1",
    "BUN_CONFIG_HTTP_KEEP_ALIVE_TIMEOUT": "60",
    "BUN_CONFIG_HTTP_CONNECT_TIMEOUT": "30"
  }
}

Suggested fixes / asks for maintainers:

  1. Serialize or queue the startup fetches (Bootstrap, MCP registry, claudeai-mcp, /v1/messages session-title generation) so they don't all race against a freshly-constructed mTLS agent.
  2. Honor BUN_CONFIG_HTTP_RETRY_COUNT in the MCP registry / Bootstrap codepaths (currently logs no more retries left on first failure).
  3. Reuse a single HTTPS agent across startup requests instead of constructing one per request.
  4. Add a CLI flag / env var to disable the server-side connector registry (tengu_claudeai_mcp_connectorc). The current behavior makes unlinked connectors (e.g. "Microsoft 365") unconditionally polled with no working auth, returning 401 on every startup. Related: #14490, #20873.
  5. Treat ECONNRESET during startup as transient and retry transparently with backoff before surfacing the error to the user.

Related issues:

  • #60133 — Socket closed during long agentic sessions
  • #49761 — OAuth: socket connection closed
  • #51107 — Socket connection closed during API request
  • #14490 — --strict-mcp-config does not override disabledMcpServers
  • #20873 — Feature request: --no-mcp, --no-plugins, --no-agents flags

Happy to provide further reproductions, full debug logs, or test patches.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗