[BUG] API Error: Connection closed mid-response ==> frequent enough to make Claude Code unusable for any task
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?
Summary
"API Error: Connection closed mid-response. The response above may be incomplete."
occurs frequently during normal usage. The response is cut off mid-generation with no way
to recover it.
Environment
- OS: Windows 11 / WSL2 (Ubuntu, kernel 6.18.33.1-microsoft-standard-WSL2)
- RAM: 64 GB
- Claude Code: latest version
- IDE: VSCode (latest), Claude Code extension (latest)
- Proxy: none
- Network: direct connection, no corporate firewall
Reproduction
The error occurs consistently when Claude generates long responses — for example,
reading multiple large files and producing a structured report. It does NOT require
any special conditions: no proxy, no low memory, no version mismatch.
Key observation
The same task on the same machine with the same network does NOT produce this error
with any other AI assistant (e.g., GitHub Copilot, Cursor, GPT-4). This strongly
suggests the issue is on Claude Code's streaming layer, not the environment.
Impact
The error is frequent enough to make Claude Code unusable for any task that produces
long responses. The user has to restart and retry repeatedly, often unsuccessfully.
Expected behavior
Long responses should complete normally or, at minimum, be resumable after a
connection drop.
Related issues
- #26285
- #67766
What Should Happen?
I just want that Claude works.
Error Messages/Logs
API Error: Connection closed mid-response
Steps to Reproduce
- Try to use Claude inside VScode or CLI.
Claude Model
Not sure / Multiple models
Is this a regression?
No, this never worked
Last Working Version
_No response_
Claude Code Version
2.1.181
Platform
Anthropic API
Operating System
Windows
Terminal/Shell
WSL (Windows Subsystem for Linux)
Additional Information
_No response_
Showing cached comments. Read the full discussion on GitHub ↗
53 Comments
Adding the unattended / auto-accept angle, plus an auto-resume proposal
This error is especially painful in auto-accept / autonomous mode, where the whole point is to let Claude Code work unattended through a multi-step task. A single mid-stream drop halts the run and forces a human back to the keyboard to type
continueand re-establish context — which defeats unattended operation. On long or data-heavy responses (large file reads, big tool/MCP output) the drop rate is high enough that long autonomous runs can't be trusted to finish on their own.Why the existing retry logic doesn't cover this: Claude Code already retries transient failures at the start of a request (~10× with backoff), but a stream dropped mid-response is not retried — the partial response and any in-flight tool calls are simply lost, and there's no snapshot to replay.
--continue/--resumeonly reopen the transcript; the resumed session carries no marker that it was cut off, so a human still has to notice and re-prompt.#26729 proposed essentially this (detect network loss, save in-flight state, auto-resume on reconnect) and was closed as not planned. Given how much it undermines unattended/auto-accept usage, I'd like to make the case for reconsidering it. A bounded version:
Edit/Bash— so they aren't blindly re-run; read-only tools can be safely retried.Suggested configuration:
CLAUDE_CODE_AUTO_RESUME_ON_DROP=1— default on in headless / auto-accept mode, prompt in interactive.CLAUDE_CODE_MAX_RESUME_ATTEMPTS=3— bounded, with backoff; give up gracefully and print recovery instructions if exceeded.Even just layers 1 + 3 (clean detection + automatic re-issue of the dropped turn) would remove most of the babysitting burden in auto mode, without requiring full mutation-aware state recovery up front.
Follow-up: the detection half of this already ships in the CLI — only the resume half is missing
Inspecting the installed CLI (v2.1.186), Claude Code already carries stream-stall detection infrastructure. The relevant (currently undocumented) env vars and behavior:
CLAUDE_ENABLE_BYTE_WATCHDOG, default on. Wraps the HTTP response body, timestamps every chunk, and aborts if no bytes arrive within an idle window (≈3 min on the first-party API, tunable viaCLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS, clamped ~1 ms–30 min). Emitstengu_byte_watchdog_firedwithidle_ms/readable_errored/body_read_pending.CLAUDE_ENABLE_STREAM_WATCHDOG, default off, but forced to"1"in background/daemon sessions. Detects gaps between parsed SSE events; deadline ismax(CLAUDE_STREAM_IDLE_TIMEOUT_MS, 300000)(floored at 5 min). Emitstengu_streaming_stall("Streaming stall detected: …s gap between events").keepPartialMessageOnAbort— already retains the partial assistant text when a stream is aborted. This is exactly what prints "The response above may be incomplete."So layer 1 of the #26729 proposal (detect the drop, abort cleanly) is effectively already implemented, and the partial response is even preserved. What's missing is layer 3 (auto-resume): after the watchdog aborts mid-response, the turn is not re-issued — the user has to manually
continueand re-establish context.For unattended / auto-accept runs (which, per the above, already run with the stream watchdog enabled), wiring the existing abort path into an automatic re-issue of the interrupted turn — injecting a marker that the previous response was truncated so completed work isn't redone — would close the gap with relatively little new machinery, since detection and partial-state capture are already present.
(Behavior observed via
stringson the installed binary; these env vars appear undocumented, so the exact names/defaults may change between releases.)Same issue hit today in claude code. No VPN, no special firewall, no new setup, never hit these issues previously.
Please give us a better way to avoid or handle these errors for big context long running tasks.
Corroborating from a different environment — this is not WSL2-specific, so it rules out the WSL2/Windows theory:
Environment
When it hits us
Most frequently during long autonomous / agentic sessions — many turns of heavy tool use (shell commands, background tasks/subagents) with a large accumulated context. The longer the session and the bigger the context, the more often the stream drops with:
Why it's especially costly for agentic use
Long multi-step autonomous work is exactly Claude Code's strongest use case. When the connection drops mid-response the model is usually mid-task (mid tool-plan, mid-report); the partial output can't be resumed and the whole turn has to be restarted, losing the in-flight reasoning. For long-running / background agent loops this turns a reliable workflow into a coin-flip.
+1 to the SSE-heartbeat proposal in #70017 — a periodic keepalive during long generation/reasoning, plus graceful mid-stream resume, would directly address this. Same machine + network does not reproduce this with non-Claude tooling, matching the original report. Happy to share timing/frequency data if useful.
Same issue hit today in claude code. And if it occurs once, no matter how many times you retry, it will always fail the same way, which will exhaust all your tokens
This has started happening to me from time to time over the last week or so, with irregular frequency. Nothing in my setup has changed. I'm using Claude Code VS Code Extension.
This has been happening to me inconsistently on version of claude cli v2.1.195.
<img width="672" height="71" alt="Image" src="https://github.com/user-attachments/assets/4d5161b1-efbc-40b0-99af-18544d3ad64f" />
Context memory when it was hit :
<img width="670" height="244" alt="Image" src="https://github.com/user-attachments/assets/c8a1e351-7c3e-4fe4-b7ed-676a28c41c1e" />
Nothing unusual on load of work.
Encountering the same issue in claude code latest build (2.1.195) on macos since the last 2 days.
Its just constant happening. No alternative. No flushing the the conversation. Compact does nothing. Everything I spent $$$ working with it beforehand is unusable because the conversation can't go anywhere now.
<img width="372" height="535" alt="Image" src="https://github.com/user-attachments/assets/24ddfcf5-3083-42e3-9035-6ea8a02aff30" />
Same issue on Windows 11 on ARM (Snapdragon) — adding a platform data point, since the reports here so far are mostly macOS / Linux / WSL / VSCode.
Environment
Symptoms (multiple times a day for the past week):
Connection went idle — The response stream stopped before finishing — try again in a moment.API Error: Connection closed mid-response. The response above may be incomplete.Happens most often partway through longer responses and right after tool calls. "Try again" usually resumes and committed work survives, but it's frequent enough to be genuinely disruptive.
Local network ruled out: at the time of the drops,
ping api.anthropic.comshowed 0% packet loss / ~52 ms avg over 20 packets, Wi-Fi at 100% signal, and status.claude.com listed all services Operational. So in my case this is a server-side stream termination, not local connectivity — worth flagging because these errors are easy to misattribute to the user's network.+1 for a fix, or the SSE-heartbeat mitigation proposed in #70017.
Same issue here on Claude Desktop for macOS.
Device: MacBook Pro M5 Pro
OS: macOS Tahoe 26.5.1
Can confirm I'm experiencing the same behavior.
The chances are it's the API_TIMEOUT_MS var or the CLAUDE_STREAM_IDLE_TIMEOUT_MS. I set both of them to 36000000ms and now it's brewing for the few hours straight
Adding a data point plus a workaround that resolved this for me.
Same symptom:
API Error: Response stalled mid-stream. The response above may be incomplete.— the sibling wording of "Connection closed mid-response". It hit me repeatedly on v2.1.199 (thelatestchannel), during exactly the runs described here: long, large-context, autonomous/agentic sessions with heavy tool output. Typingcontinuewould buy a few more minutes before it stalled again.What fixed it for me: moving off the
latestchannel back to thestablebuild. On 2.1.199 the stalls were frequent; since switching to stable (v2.1.191) I haven't reproduced it.Claude Code has a native release-channel setting, so you don't have to disable auto-update to stay pinned:
Then reinstall the stable build once (switching the channel alone won't downgrade you):
After that the auto-updater tracks the
stablechannel only — it won't jump back tolatest/preview builds, but you still get future stable fixes. (There's also aminimumVersionsetting to guard against downgrades.)Caveats, so this doesn't mislead anyone: this is anecdotal / n=1, and I see others here hit it on 2.1.186 and 2.1.195 — so it's plausible this is really a specific regressed
latestbuild (2.1.199 in my case) rather than the stable/latest distinction as such. Sharing it because it's cheap to try and it cleanly stopped the stalls for me.just hit this over the last night. nothing i have tried has worked to resolve it so far.
issue occurs on macbook pro, m4 max.
seems to have started randomly, no version change prior. claude-code ran a long running multi-agent workflow successfully for a few hours, before it stopped getting a response from the api in the middle of that workflow
Im frequently hitting this issue for few weeks now already its super annoying... Im on a Starlink connection which drops out every now and then for a bit. Not sure if it's related to that but at the end, it should recover from this and not get stuck forever so that you need to nudge it to keep going...
the only way that i have found "helps" getting around this is to compact, and drop the effort down a level, and then prompt claude-code to do some tiny incremental version of the original prompt, and specify that it should work in small batches for that stage in the work... isn't great because it breaks my workflow to manually go in and investigate+prompt out of it.
im certain my little prompt ritual is not the minimal number of steps to resolve it, but it was the last set of things i did before i got it moving again... going to have to cargo cult this for now.
I ran into the same issue, starting from approx. 3 weeks ago, both on Windows 11 and Ubuntu 24. >50% of prompts resulted in the Connection closed mid-response error. After lots of debugging, the thing that solved it for me right now was to disable IPv6 completely. I have no idea whether the problems are with my local network setup, with my ISP, or further upstream, but by enforcing everything over IPv4 I have had no issues anymore.
No idea if this is feasible for others, but worthwhile to try if you're running into this.
Confirming this on a different platform and path — Claude Code 2.1.202, macOS (darwin) — so it isn't Windows/WSL-specific.
Quantified from JSONL transcripts (ground-truthed via
isApiErrorMessage: true, to exclude quoted/echoed occurrences): 11 genuineConnection closed mid-responseevents in a single ~4.5 h session, concentrated on long Agent-tool (Task) subagent turns. Each affected subagent transcript ends exactly at the error record — the subagent dies mid-turn with no in-agent retry/resume; it only recovered because a parent orchestrator re-dispatched it (and a naive re-dispatch of the same large turn dropped again).So the failure spans foreground and background/subagent paths, across Windows/WSL and macOS. Your "should be resumable after a connection drop" expectation is exactly right; full forensics + the concrete prevention (server-side SSE heartbeat, and/or a client-settable retry/resume for background Agent-tool dispatches) are in #70017.
+1 — getting the same issue.
API Error: Connection closed mid-response. The response above may be incomplete.shows up during normal usage and the response is cut off with no way to recover it.One data point that may help triage: this issue is labeled
platform:wsl, but I'm hitting the same error on macOS with a direct connection, so it doesn't appear to be WSL/Windows-specific.Environment:
happens constantly
Keeps occurring regardless of Anthropic subscription or AWS Bedrock hosted model instance, even when switching mid session.
Same issue here
Same issue here
Just hit this, only affects one of the chats i have only. The others work fine. Started suddenly on Claude CLI (latest as of today), on Windows
Adding a rate-normalized macOS data point
Environment
Rate, not just counts. Absolute error counts mostly track how heavy the day was, so they're misleading. Genuine errors ÷ assistant turns per day (July):
| date | genuine drops | assistant turns | rate |
|------|--------------:|----------------:|-----:|
| 07-05 | 27 | 3172 | 0.9% |
| 07-06 | 29 | 4610 | 0.6% |
| 07-07 | 49 | 6144 | 0.8% |
| 07-08 | 21 | 6803 | 0.3% |
| 07-09 | 35 | 11119 | 0.3% |
| 07-13 | 36 | 4905 | 0.7% |
| 07-14 | 33 | 2218 | 1.5% |
Baseline sits at ~0.3–1.0%; drops are mid-stream on long/heavy agentic turns (large multi-file reads, big tool/MCP output, subagent turns), never at connect time — live IPv4/IPv6 TLS handshakes to
api.anthropic.comare both ~30–70ms and healthy while streams still die minutes in. Spans every workspace + subagent transcripts, so it's the streaming layer, not any project.Client-side resilience is already exhausted on my end and doesn't cover it:
CLAUDE_CODE_MAX_RETRIES=15,CLAUDE_CODE_RETRY_WATCHDOG=1,CLAUDE_STREAM_IDLE_TIMEOUT_MSandCLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MSboth at 20 min. The byte/stream watchdog fired only 3× ever, so these are not premature-timeout kills — and retries only fire at request start, so a mid-stream FIN is unrecoverable. This is exactly the gap @delor / @asawicki describe: detection + partial capture exist, auto-resume doesn't.Sample requestIds (all genuine mid-stream drops, 2026-07-14 UTC):
32 of 34 today's drops carry requestIds; happy to share the full list or timing/frequency data if it helps triage.
+1 to the SSE-heartbeat + resumable-stream proposals (#70017). A server-side keepalive during long generation, and/or a client-settable retry/resume for background Agent-tool dispatches, would directly address this.
Update to my comment above. The increased error rate today (1.5%) has been attributed to an advanced Endpoint Detection and Response (EDR) system extension crash-looping, driving high CPU.
The root problem w/ Claude Code disconnects is still occurring but at a normal frequency forcing me to keep prodding the harness to "try again" or "continue".
Same issue here. Had to stop using Auto Mode due to this problem
We have a similar problem on our workload that involves a long running multi-agents system would be great we get ETA on timeline to fix this
Facing the same issue in Claude code vs code extension.
Happened to us again.
Same failure mode as this issue: a Claude Code session driven via Remote Control hit repeated Login expired · Please run /login. When I typed /login, it responded /login isn't available over Remote Control — so the session is completely stuck: it demands a re-login but offers no way to do it remotely.
Impact: the agent is effectively bricked mid-task from the remote side. The only recovery is going back to the machine physically to run /login, which defeats the purpose of Remote Control.
Repro: run a long Claude Code session, drive it from Remote Control (mobile), let the auth token expire → Login expired loop with no usable /login path over Remote Control.
Would be great if /login (or a re-auth flow) were supported over Remote Control, or if sessions warned/refreshed auth before expiry.
<img width="1080" height="2340" alt="Image" src="https://github.com/user-attachments/assets/4cc4a1af-886a-4b8b-9ba5-a371be88fe54" />
Same here.
Happening like 3-4 times in 1 prompt.
same here, very annoying
Version-normalized data point: rate jumps at 2.1.217/2.1.218 (macOS, no proxy)
Following up on @ilyasubkhankulov's rate-normalized approach — same idea, but sliced by Claude Code version and controlled for terminal emulator. Local transcripts only,
~/.claude/projects/**/*.jsonl, 14–24 Jul 2026.Environment
scutil --proxyempty, noutuncorporate tunnel, no security agents running)effortLevel: xhighCLAUDE_CODE_MAX_OUTPUT_TOKENS=64000Counting method. A "genuine error" is an assistant record with
message.model == "<synthetic>"whose first text block starts withAPI Error: Connection closed mid-response. Denominator is real assistant turns (model != "<synthetic>"). This matters: naivegrepover transcripts inflates counts badly, because the error string also appears in user pastes and in tool output when you grep your own logs. My first pass was ~3x too high for that reason.Rate by version
| Version | Assistant turns | Genuine errors | Errors / 1000 |
|---|---:|---:|---:|
| 2.1.205 → 2.1.216 (aggregate) | 10,966 | 0 | 0.0 |
| 2.1.217 | 1,895 | 2 | 1.1 |
| 2.1.218 | 1,536 | 14 | 9.1 |
Per-version detail for the clean stretch: 2.1.209 (944), 2.1.210 (1,557), 2.1.211 (580), 2.1.212 (1,303), 2.1.214 (2,022), 2.1.215 (1,703), 2.1.216 (2,620) — zero genuine errors across all of them. 20 Jul alone had 1,461 turns and 21 Jul had 2,466 turns, both clean.
The first error in ~11k turns appears the day 2.1.217 was in use, and the rate goes up ~8x on 2.1.218.
Controlling for terminal emulator
I switched terminal emulators in the same 48h window, which initially made me blame the terminal. Splitting 22 Jul (single version, 2.1.217, both emulators used) separates the variables:
| 22 Jul, Claude Code 2.1.217 | Assistant turns | Errors | Errors / 1000 |
|---|---:|---:|---:|
| Native terminal (Ghostty) | 701 | 0 | 0.0 |
| Electron terminal (Orca) | 1,021 | 2 | 2.0 |
| Electron terminal held constant | Assistant turns | Errors | Errors / 1000 |
|---|---:|---:|---:|
| 2.1.217 | 1,021 | 2 | 2.0 |
| 2.1.218 | 1,536 | 14 | 9.1 |
With the emulator held constant, the rate still rises ~5x on 2.1.218. The terminal does not account for the jump.
Other observations
529 Overloadedand zero 5xx synthetic errors on the affected days. The connection drops are isolated, not accompanied by load shedding.Live capture while writing this report
Two drops hit the very session I was using to compile these numbers, 110 seconds apart:
| Timestamp (UTC) | Context at drop | What was happening |
|---|---:|---|
| 2026-07-24 00:58:00 | 149,031 tokens | 2s after the first text token, following a reasoning block |
| 2026-07-24 00:59:50 | 151,225 tokens | same pattern |
That session: 2 drops in 79 assistant turns (~25/1000, ~3x the 2.1.218 average). Both landed at ~150k context — well under the 329k median — which further argues context size is not the driver. In both cases the model had just finished a reasoning block and emitted its first sentence, and the stream died ~2s later.
Caveats
Single machine, single user. The error counts are small in absolute terms (2 and 14), so the per-version rates carry wide confidence intervals. I cannot rule out a server-side change that happened to land in the same 22–23 Jul window. What is robust is the denominator: 0 errors in 10,966 turns on 2.1.205–2.1.216 under the same network, same account, same workload profile.
Repro script
Happy to run any instrumented build against the same workload if that would help narrow it down.
Hitting this so frequently today with Opus 5 and Claude Code 2.1.220 that it is making Claude Code completely unusable.
Tried effort xhigh, high and medium. All those effort levels reproduced the issue.
Por aca el mismo error:
● API Error: Connection closed mid-response. The response above may be incomplete.
Entorno:
VPS windows server 2022 standard
Pruebas
Con diferentes modelos fable, opus, sonet, con diferentes esfuerzos, sigue dandoe el mismo error de forma aleatoria, incluso a iniciar una tarea, por ahora solo le digo continua y sigue.
Same thing on macOS. Sick of burning through so many tokens because of this.
Harness-side analysis: why this error never self-recovers (v2.1.220 native binary)
Not a fix, but the retry logic explains the "type
continue" ritual everyone in this thread is doing — and there's one undocumented env flag that helps the adjacent failures.1. There IS a mid-stream retry, but it's gated on having emitted nothing but thinking
In the streaming error handler, after a connection drop CC checks whether any non-thinking block has already been yielded. If only thinking blocks went out, it retries the stream:
(telemetry:
tengu_streaming_stale_connection_retry,tengu_streaming_watchdog_retry)Limits are hardcoded — 2 stale-connection retries, 1 idle-timeout retry. No env override.
The moment a single text or
tool_useblock has streamed, the retry branch is skipped entirely and it takes the finalize path:(telemetry:
tengu_streaming_partial_finalized)…which synthesizes a
stop_reason(tool_useif a tool_use block was in flight, elseend_turn) and writes the message we all see to the transcript withisApiErrorMessage: true.The design is coherent — resuming the stream would duplicate text already printed — but the consequence is that the longer and more useful the turn, the more certain it is that no retry is even attempted. That matches the reports here: it's the long multi-file, multi-tool turns that die, and the trivial ones that quietly recover.
2. No hook can rescue it either
The turn-end fires
StopFailure, notStop. From the binary's own description of the event:So the usual
Stop-hook trick (decision: "block", or exit 2) cannot auto-continue an API-error turn, because aStophook never runs for it. The only user-side workaround left is an external process watching the terminal and typingcontinue— which is where several people in this thread have ended up.3. Undocumented flag that helps the adjacent failures:
CLAUDE_CODE_RETRY_WATCHDOG=1It does not affect the after-output case above, but at the request level it:
CLAUDE_CODE_MAX_RETRIESclamp (otherwise silently capped at 15)tengu_api_529_background_dropped)That last one matters for the multi-agent reports above: a subagent hit by this dies as "Agent terminated early due to an API error" and the parent only learns about it via a failed task notification.
Two asks
stop_reason; a synthetic continuation is strictly better than a human typingcontinue, and it's the same tokens either way.StopFailureblockable (honourdecision: "block"/ exit 2) so users can implement (1) themselves while (1) is pending.---
Environment: Claude Code 2.1.220, native install, Linux x86_64 (Ubuntu 24.04), direct to
api.anthropic.com, no proxy, no VPN. Minified symbol names will drift between versions; the log strings and telemetry event names above are the stable handles to grep for.Adding quantified data from a heavy-usage instance, since most reports here are qualitative. I mined my local
~/.claude/projects/*.jsonltranscripts and computed the error rate with a denominator (assistant turns). It shows a sharp onset rather than a constant background rate.Environment: macOS (darwin arm64), VS Code extension, Claude Code 2.1.220, Node v22.20.0, direct connection — no proxy, no
HTTPS_PROXY/NODE_EXTRA_CA_CERTS, no TLS-inspecting agent.Error rate by day (
Connection closed mid-responseevents / assistant turns):| date | errors | assistant turns | rate |
|---|---|---|---|
| 2026-07-23 | 3 | 5,883 | 0.05% |
| 2026-07-24 | 0 | 9,043 | 0.00% |
| 2026-07-25 | 17 | 6,238 | 0.27% |
| 2026-07-26 | 4 | 7,256 | 0.06% |
| 2026-07-27 | 0 | 6,392 | 0.00% |
| 2026-07-28 | 0 | 13,891 | 0.00% |
| 2026-07-29 | 0 | 5,110 | 0.00% |
| 2026-07-30 | 120 | 7,276 | 1.65% |
| 2026-07-31 | 128 | 4,521 | 2.83% |
A ~50x step change on 2026-07-30, at lower usage than 07-28.
Hypotheses ruled out with this data:
claude-opus-5was already dominant on 07-28 (7,309 turns, 0 errors).Sample: 276 error events across 1,237 session files.
The step-change shape — flat ~0% for days, then 50x overnight on an unchanged client, unchanged network path, and smaller payloads — looks server-side rather than client-side. Happy to supply request IDs or run specific instrumentation if that would help narrow it.
This cluade mid-response issue happened to me on windows 10, today. I tried to test on fable/opus, but it's still the same issue.
Same problem
me too, running into the error "API Error: Connection closed mid-response. The response above may be incomplete." again and again (using VS Code)
this issue is finally resolved when I degrade the Claude extension version to 2.1.220 in my case. if you're urgent about this issue, I hope you can try to do the same.
+1, seeing this too — but even worse: it's not just long responses, even a single-word message like "hi" fails with the same error.
Environment:
Already ruled out:
curl.exe -v https://api.anthropic.com/v1/messagesat the exact same time as a Claude Code failure returns a normal response (401 without API key, as expected)Since a simple "hi" fails and plain curl to the same endpoint works fine at the same moment, this really does point to something specific in how the Claude Code client handles the connection/stream, not a general network problem on my end.
it works, thank you very much
same problem
TL;DR: found the root cause on my end, and a workaround that's been rock-solid for 5 days straight (zero errors, across 2 machines) — sharing in case it saves someone else the same rabbit hole. But to be clear: this is a workaround, not a fix, and I think Anthropic needs to address it on their end.
This turned out to be a home network / router issue, not a Claude Code bug per se — but the router misbehavior only surfaces because of how Claude Code streams long responses, so it's worth documenting here.
Setup: Windows 11 + WSL2, consumer router (Huawei BE3), PPPoE, MTU 1492.
Root cause (confirmed via packet-level testing, done jointly with my ISP's technical support):
Prevent ICMP flood/smurf/echo-reply+Prevent ping of death) rate-limits/drops outbound "Fragmentation Needed" ICMP replies under real load.Cross-validation this isn't a Claude Code–specific bug:
Important: other coding agents on the exact same network don't have this problem. OpenCode, Codex, and Google Antigravity all run fine here without any workaround. So while the trigger is network-side (a fragile PMTUD path on a consumer router), other clients are clearly handling it more gracefully — whether that's smaller frame sizes, retry logic, or something else in their streaming layer. This points to something Claude Code's streaming implementation could be more resilient to, not just a "your network is broken" situation.
Workaround — running clean for 5 days now, 0 errors on either machine:
Cloudflare WARP (Zero Trust client, full-tunnel mode) sidesteps the whole problem — WARP does its own MSS clamping inside the WireGuard tunnel, so it doesn't depend on the local network's PMTUD path at all.
For anyone hitting this behind a consumer router without MSS clamping, the permanent fix is a router that supports it, e.g. on MikroTik/RouterOS:
Given other tools don't hit this on the same broken network path, I'd really encourage the team to look at making the streaming layer more resilient to path-MTU blackholes (e.g., detecting a stall and retrying with a smaller frame/segment size) instead of leaving it entirely on users to fix their network.
I'm hitting this at least once per hour since 2 days ago.
Data point: neither of the two workarounds in this thread holds up here — measured, with the commands so others can check
Adding hard numbers, because the last few pages have converged on two theories (downgrade to 2.1.220; router PMTUD blackhole) that I could rule out for my environment. Both are worth testing before anyone reconfigures their router or pins an old build.
Environment: macOS (Apple Silicon), Claude Code VS Code extension, Opus, home connection, no VPN/proxy.
1. The version-regression theory doesn't fit my history
The suggestion upthread is that 2.1.221+ regressed and 2.1.220 is clean. I counted the actual failures in my own transcripts (
~/.claude/projects/**/*.jsonl, only entries with"isApiErrorMessage": true) — 38 confirmed events:These start 2026-06-21. Extension 2.1.221 was published 2026-08-04, and 2.1.220 itself only on 2026-07-25 — so the June and most of the July failures predate both. A 221+ regression cannot explain them. Nor is there a step change in density: 2026-07-11/12 was 9 events in two days, comparable to 2026-08-04..08. I downgraded to 2.1.220 anyway to test it, then reverted, since the data doesn't support it.
Count your own with:
(Filtering on
isApiErrorMessagematters — a plain grep also matches sessions where the string merely appears in conversation text.)2. The PMTUD / router theory doesn't apply either
Re @luciancsilva's excellent write-up above: that root cause is real but specific to a path with a reduced MTU (PPPoE 1492) plus a router that drops ICMP "fragmentation needed". My path is clean at full 1500 with the DF bit set, all the way to the API:
| Destination | 1300 | 1442 | 1480 | 1500 |
|---|---|---|---|---|
| local gateway | OK | OK | OK | OK |
| 1.1.1.1 | OK | OK | OK | OK |
| 160.79.104.10 (api.anthropic.com) | OK | OK | OK | OK |
Interface MTU is 1500, no PPPoE encapsulation. A 25 MB inbound HTTPS transfer completes in 1.7 s (~15 MB/s) with no stall, so large inbound segments are not blackholing. Cloudflare WARP would be a no-op here.
Conclusion
At least in my case this is a baseline failure class independent of client version and independent of local path MTU — which matches the several reports here of drops on clean corporate networks and on
curl-verified-healthy connections. Suggest treating the two workarounds as environment-specific rather than general fixes; running the two checks above takes a minute and tells you which bucket you're in.Given that, the server-side SSE heartbeat proposed in #70017 remains the only mitigation that would cover this class of failure for everyone. +1 to that, and to exposing a resume path for background/Agent-tool dispatches, which today get no retry at all once the stream has emitted output.
As someone hoping to have my tasks run automatically in the Claude Code terminal for an extended period, I encountered a very frustrating situation: "API Error: Connection closed mid-response. The response above may be incomplete." This problem occurred frequently, and unlike other issues, Claude Code didn't automatically retry.
<img width="1472" height="756" alt="Image" src="https://github.com/user-attachments/assets/ec2deba0-c2ae-475b-8fcb-16b6b14562b8" />
Previously, my usual approach was to manually send "please, retry" or "please continue" messages, but as shown in the image below, the frequent terminal interruptions became tiresome.
<img width="1468" height="1698" alt="Image" src="https://github.com/user-attachments/assets/b551e58d-4c7d-4901-ab97-310c3de478fa" />
My solution isn't particularly sophisticated, as I'm not fully familiar with the underlying architecture and network stability. I tried all the methods I found online, and when all else failed, I tried monitoring the terminal and having it resolve the issue automatically.
<img width="2940" height="1912" alt="Image" src="https://github.com/user-attachments/assets/68c646e1-d01a-473d-b4f0-c53c9769a5be" />
The core logic is:
1) A "failure" hook—Claude Code has an event called StopFailure, which is triggered when a conversation crashes due to an API error. I attached a small script to it. It can't let the session continue on its own (Claude Code explicitly ignores any returns from these hooks), but it can leave a note: "Terminal window #3 just crashed."
2) A background daemon—it picks up the note and then uses macOS's built-in automation (AppleScript) to actually type "please, retry + Enter" into that terminal. It does exactly the same thing you would do manually, except it doesn't need to be watched.
3) A fallback "scan"—if the hook doesn't trigger, the daemon scans the screen content of all terminals every 5 seconds, checking the layout: Was the last thing the error message? Did it stop? Are the input boxes empty?
For example: the hook is like a doorbell, and the screen scan is like patrolling the building every 5 seconds. The doorbell is faster and more accurate, and the patrol ensures nothing is missed.
Currently, the result meets my expectations; essentially, this project automatically monitors the terminals for me.
Because I believe that even better methods may emerge in the future, and I also find the ability to monitor terminals and directly issue commands to them truly exciting and highly scalable. To facilitate future sharing and reference, I've open-sourced my method on this GitHub address: https://github.com/S313S/claude-code-autoresume. Everyone is welcome to use the agent to understand and learn from it.
I also want to express my sincere gratitude to the predecessors mentioned above for their guidance.
<img width="1387" height="635" alt="Image" src="https://github.com/user-attachments/assets/6683665b-f911-46de-b747-b79a3e61c5d3" />
claude --version
2.1.226 (Claude Code)
Same here
Current version: 2.1.227
Checking for updates to latest version...
Claude Code is up to date (2.1.227)
We use Opus from ms foundry
I also faced this issue, turns out my cloudflare warp cli. I disconnected it and the issue solved.
I am also plagued by those frequent API connection errors (and was also able to trace it down to what looks like a NAT timeout, but it looks like it is on the Anthropic side, not on my side - and only for the Claude Code data connections, not for the remote control connections).
Eventually I added this to my
CLAUDE.md, which is a workaround that seems to work:This is obviously not an ideal solution (it isn't even a solution, it is just a workaround), but at least it keeps the agents alive despite them running into those API errors many times per hour.