Intermittent `socket connection was closed unexpectedly` (ECONNRESET) on startup — ~40-70% failure rate across parallel startup fetches
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(bundledbunruntime) - OS: Windows 11 Enterprise (pt-BR)
- Node v24.3.0 (per
x-stainless-runtime-versionin debug log) - Account: Claude Max, authenticated
- Network: wired, no VPN, no corporate proxy (
HTTPS_PROXYempty,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:
- Four parallel endpoints fail simultaneously in ~167ms —
Bootstrap,MCP registry,claudeai-mcp, and/v1/messages?beta=true. mTLS: Creating HTTPS agent with custom certificatesis logged 3–4 times within milliseconds on every startup — each request appears to construct its own agent rather than share a pool.no more retries leftis logged even thoughBUN_CONFIG_HTTP_RETRY_COUNT=3is set — this code path is not honoring the retry config.- The erroe is ECONNRESET (TCP RST), not a clean FIN or HTTP-level error.
- When the request succeeds,
cf-rayandserver: cloudflareheaders 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:
- Serialize or queue the startup fetches (
Bootstrap, MCP registry,claudeai-mcp,/v1/messagessession-title generation) so they don't all race against a freshly-constructed mTLS agent. - Honor
BUN_CONFIG_HTTP_RETRY_COUNTin the MCP registry / Bootstrap codepaths (currently logsno more retries lefton first failure). - Reuse a single HTTPS agent across startup requests instead of constructing one per request.
- 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. - 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-configdoes not overridedisabledMcpServers - #20873 — Feature request:
--no-mcp,--no-plugins,--no-agentsflags
Happy to provide further reproductions, full debug logs, or test patches.
This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗