[BUG] API Error: Connection closed mid-response ==> frequent enough to make Claude Code unusable for any task

Status Closed — duplicate
Reported on v2.1.181
Maintainer reply None cached
Activity 55 comments · opened Jun 18, 2026 · closed Aug 19, 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?

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

  1. 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_

View original on GitHub ↗

53 Comments

delor · 2 months ago

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 continue and 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 / --resume only 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:

  1. Stream watchdog — detect the drop (the existing "no data for 20s" banner is a start) and abort the partial turn cleanly instead of dead-ending with an unrecoverable error.
  2. Recovery snapshot — persist conversation state up to the last complete message plus the in-flight prompt. Record completed tool calls — especially mutations like Edit/Bash — so they aren't blindly re-run; read-only tools can be safely retried.
  3. Auto-resume — re-issue the interrupted turn automatically, injecting a marker such as "previous response was truncated by a connection drop; continue from the last completed step" so the model doesn't redo finished work.

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.

delor · 2 months ago

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:

  • Byte watchdogCLAUDE_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 via CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS, clamped ~1 ms–30 min). Emits tengu_byte_watchdog_fired with idle_ms / readable_errored / body_read_pending.
  • Event/stream watchdogCLAUDE_ENABLE_STREAM_WATCHDOG, default off, but forced to "1" in background/daemon sessions. Detects gaps between parsed SSE events; deadline is max(CLAUDE_STREAM_IDLE_TIMEOUT_MS, 300000) (floored at 5 min). Emits tengu_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 continue and 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 strings on the installed binary; these env vars appear undocumented, so the exact names/defaults may change between releases.)

peculiar-ragdoll · 2 months ago

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.

honzastim · 2 months ago

Corroborating from a different environment — this is not WSL2-specific, so it rules out the WSL2/Windows theory:

Environment

  • OS: Linux (native, not WSL2)
  • Claude Code CLI (latest), model Claude Opus 4.8 (1M context)
  • Direct connection, no proxy, no corporate firewall, high-RAM workstation

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:

API Error: Connection closed mid-response. The response above may be incomplete.

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.

kaelzhang · 2 months ago

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

Shadetail · 2 months ago

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.

komalkotkartrex · 2 months ago

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.

shameekbaranwal · 2 months ago

Encountering the same issue in claude code latest build (2.1.195) on macos since the last 2 days.

yarhouse · 2 months ago

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" />

afram123 · 2 months ago

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

  • Claude Code v2.1.195 (desktop app)
  • Windows 11 Home, build 26200 — Snapdragon X Plus (X1P42100), ARM64
  • Model: Opus 4.8

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.com showed 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.

n-kulic · 2 months ago

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.

Imyamoe · 1 month ago

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

gobylor · 1 month ago

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 (the latest channel), during exactly the runs described here: long, large-context, autonomous/agentic sessions with heavy tool output. Typing continue would buy a few more minutes before it stalled again.

What fixed it for me: moving off the latest channel back to the stable build. 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:

// ~/.claude/settings.json
{
  "autoUpdatesChannel": "stable"
}

Then reinstall the stable build once (switching the channel alone won't downgrade you):

npm install -g @anthropic-ai/claude-code@stable

After that the auto-updater tracks the stable channel only — it won't jump back to latest/preview builds, but you still get future stable fixes. (There's also a minimumVersion setting 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 latest build (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.

indoorhill · 1 month ago

just hit this over the last night. nothing i have tried has worked to resolve it so far.

  • tried upgrade to latest, v2.1.201
  • tried downgrading to stable, v2.1.193
  • tried compacting (context was at 15% before though, which is not a lot)
  • tried clearing context, re-running
  • tried different network

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

xdustinface · 1 month ago

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...

indoorhill · 1 month ago

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.

slknijnenburg · 1 month ago

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.

asawicki · 1 month ago

Confirming this on a different platform and pathClaude 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 genuine Connection closed mid-response events 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.

dharmveerjakhar · 1 month ago

+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:

  • OS: macOS 26.5.2 (Build 25F84), Apple Silicon (arm64)
  • Claude Code: 2.1.204 (CLI)
  • Terminal: iTerm2 / zsh
  • Node.js: v24.18.0
  • Proxy: none (no proxy env vars set, no corporate firewall)
davidysoards · 1 month ago

happens constantly

tillik · 1 month ago

Keeps occurring regardless of Anthropic subscription or AWS Bedrock hosted model instance, even when switching mid session.

luciancsilva · 1 month ago

Same issue here

jimiflowers · 1 month ago

Same issue here

rarepops · 1 month ago

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

ilyasubkhankulov · 1 month ago

Adding a rate-normalized macOS data point

Environment

  • macOS (darwin 25.5.0), Apple Silicon
  • Claude Code 2.1.209 (CLI), Anthropic API direct (no Bedrock/proxy)
  • Direct connection; confirmed not WSL/Windows-specific (matches @dharmveerjakhar / @honzastim / @asawicki)

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.com are 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_MS and CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS both 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):

req_011Cd2TpzTJgnRe87ty2cPPM  18:59:09
req_011Cd2U3SsdM2FdXjXAKjXwm  19:01:54
req_011Cd2UbncvR7htqF1sWGA72  19:09:16
req_011Cd2W3xd2RfVFaKmLzf478  19:28:19
req_011Cd2WF8ephYH2pmfSrURh6  19:30:58
req_011Cd2WPWwFCwd4J9t7NG2KP  19:32:41
req_011Cd2Wg5m9NLYWh47GZJUHY  19:36:37
req_011Cd2WqFtbRVJaAQxHpLNxr  19:45:16

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.

ilyasubkhankulov · 1 month ago

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".

byuufx · 1 month ago

Same issue here. Had to stop using Auto Mode due to this problem

arashsadrieh · 1 month ago

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

igdesilva · 1 month ago

Facing the same issue in Claude code vs code extension.

honzastim · 1 month ago

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" />

valerii-kuzivanov · 1 month ago

Same here.
Happening like 3-4 times in 1 prompt.

pir0c0pter0 · 1 month ago

same here, very annoying

andrescanocano · 1 month ago

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

  • macOS (darwin 25.5.0), Apple Silicon
  • Claude Code CLI, native install, auto-updates on
  • Anthropic API direct — no Bedrock, no proxy, no VPN, no EDR (verified: scutil --proxy empty, no utun corporate tunnel, no security agents running)
  • Model: Opus 4.8 (1M context), effortLevel: xhigh
  • Non-default: CLAUDE_CODE_MAX_OUTPUT_TOKENS=64000

Counting method. A "genuine error" is an assistant record with message.model == "<synthetic>" whose first text block starts with API Error: Connection closed mid-response. Denominator is real assistant turns (model != "<synthetic>"). This matters: naive grep over 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

  • No server-side co-signal. Zero 529 Overloaded and zero 5xx synthetic errors on the affected days. The connection drops are isolated, not accompanied by load shedding.
  • Context size is a weak amplifier, not the cause. Median context at the moment of the drop was ~329k tokens vs ~200k baseline; 11/16 drops occurred above 200k vs 50% of all turns. With n=16 this is suggestive at best, and there were drops as low as 85k tokens.
  • Drops frequently land right as the assistant starts emitting text after a long reasoning block, which is consistent with the SSE-heartbeat theory in #70017.

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

# python3 - ; run from ~/.claude/projects
import json, glob, collections
def genuine(d):
    if d.get('type') != 'assistant': return False
    m = d.get('message') or {}
    if m.get('model') != '<synthetic>': return False
    c = m.get('content')
    return isinstance(c, list) and any(
        b.get('type') == 'text' and b.get('text','').startswith('API Error: Connection closed mid-response')
        for b in c if isinstance(b, dict))

resp, errs = collections.Counter(), collections.Counter()
for f in glob.glob('**/*.jsonl', recursive=True):
    for line in open(f, encoding='utf-8', errors='replace'):
        try: d = json.loads(line)
        except Exception: continue
        v = d.get('version')
        if not v: continue
        m = d.get('message') or {}
        if d.get('type') == 'assistant' and m.get('model') != '<synthetic>': resp[v] += 1
        if genuine(d): errs[v] += 1
for v in sorted(resp):
    print(f'{v:10} turns={resp[v]:6} errors={errs[v]:4} rate={1000*errs[v]/resp[v]:6.1f}/1000')

Happy to run any instrumented build against the same workload if that would help narrow it down.

superstructor · 1 month ago

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.

LasDeliciasDeYaya · 1 month ago

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.

panchoavila · 1 month ago

Same thing on macOS. Sick of burning through so many tokens because of this.

mreza0100 · 1 month ago

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:

Stream connection closed (<code>) after thinking-only yield — retrying streaming (n/N)

(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_use block has streamed, the retry branch is skipped entirely and it takes the finalize path:

Stream connection closed (<code>) after N block(s) yielded — finalizing partial response

(telemetry: tengu_streaming_partial_finalized)

…which synthesizes a stop_reason (tool_use if a tool_use block was in flight, else end_turn) and writes the message we all see to the transcript with isApiErrorMessage: 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, not Stop. From the binary's own description of the event:

Fires instead of Stop when an API error (rate limit, auth failure, etc.) ended the turn. Fire-and-forget — hook output and exit codes are ignored.

So the usual Stop-hook trick (decision: "block", or exit 2) cannot auto-continue an API-error turn, because a Stop hook never runs for it. The only user-side workaround left is an external process watching the terminal and typing continue — which is where several people in this thread have ended up.

3. Undocumented flag that helps the adjacent failures: CLAUDE_CODE_RETRY_WATCHDOG=1

It does not affect the after-output case above, but at the request level it:

  • raises default retries from 10 → 300
  • lifts the CLAUDE_CODE_MAX_RETRIES clamp (otherwise silently capped at 15)
  • stops 529s on background/subagent query sources from being dropped outright (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.

{ "env": { "CLAUDE_CODE_RETRY_WATCHDOG": "1" } }

Two asks

  1. Make the partial-finalize path recoverable — auto-resume the turn with the partial assistant message as context instead of handing control back to the user. The harness already synthesizes a stop_reason; a synthetic continuation is strictly better than a human typing continue, and it's the same tokens either way.
  2. Make StopFailure blockable (honour decision: "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.

parkerproductstudio · 1 month ago

Adding quantified data from a heavy-usage instance, since most reports here are qualitative. I mined my local ~/.claude/projects/*.jsonl transcripts 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-response events / 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:

  • Client version. 2.1.220 was already in use from 07-27T18:16 and ran 19,001 turns across 07-28/07-29 with zero errors before the spike. Not a regression introduced by the version I'm on.
  • Context size. Inverted from what I expected: 07-26→07-28 ran p90 context of 713k–750k tokens (~1,900 requests >400k) at ~0% error; 07-30→07-31 ran p90 of 280k–352k at 1.65–2.83%. The larger requests were more reliable.
  • Model. claude-opus-5 was already dominant on 07-28 (7,309 turns, 0 errors).
  • Local network. 0.0% packet loss / 9.5ms avg RTT over 20 pings; 5/5 samples to api.anthropic.com at ~22ms TCP, ~45ms TLS, ~70ms TTFB.
  • A specific tool or time window. Distributed across Bash (91), Agent (44), Read (24), Edit (15), roughly in proportion to usage, across all working hours; 156 in main sessions vs 94 in subagent sessions.

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.

ykatyhoney · 26 days ago

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.

VGODIE · 24 days ago

Same problem

woifh · 24 days ago

me too, running into the error "API Error: Connection closed mid-response. The response above may be incomplete." again and again (using VS Code)

ykatyhoney · 24 days ago
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.

luhuag-lab · 23 days ago

+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:

  • OS: Windows 11
  • Node.js v24.19.0 (managed via nvm4w)
  • Claude Code v2.1.223
  • Reproduces both inside VS Code integrated terminal AND standalone Windows Terminal (so not VS Code/extension specific)
  • No proxy, no VPN, system proxy off

Already ruled out:

  • Not a proxy/VPN issue (env vars empty, system proxy disabled)
  • Not VS Code/Copilot related (reproduces in standalone terminal, and no Copilot installed anyway)
  • Not MTU/fragmentation (ping -f -l 1472 succeeds)
  • Not a Node version issue (upgraded 20.20.2 → 24.19.0, still fails)
  • Basic connectivity is fine — curl.exe -v https://api.anthropic.com/v1/messages at the exact same time as a Claude Code failure returns a normal response (401 without API key, as expected)
  • claude.ai web chat works perfectly, even for multi-thousand-word generations, zero interruptions

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.

luhuag-lab · 23 days ago
> 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.

it works, thank you very much

guanlinz · 22 days ago

same problem

luciancsilva · 22 days ago

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):

  • The router's anti-DoS firewall (Prevent ICMP flood/smurf/echo-reply + Prevent ping of death) rate-limits/drops outbound "Fragmentation Needed" ICMP replies under real load.
  • Consumer routers in this class (Huawei BE3 and similar) don't expose MSS clamping — so there's no fallback once PMTUD signaling gets dropped.
  • Result: a TCP/TLS connection sends a large segment with the DF bit set, never gets the fragmentation-needed notice, and the connection blackholes — exactly the "connection closed mid-response" symptom, and it correlates with larger payloads (Opus, high context).
  • Disabling those two firewall rules reduced the issue but didn't eliminate it in real-world (non-synthetic) use.

Cross-validation this isn't a Claude Code–specific bug:

  • Same network, same symptom in Claude for Excel too (different client, same transport-layer problem).
  • Corporate network (different router): zero issues.
  • Second machine, same home network, same symptom.

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:

/ip firewall mangle add chain=forward tcp-flags=syn protocol=tcp action=change-mss new-mss=clamp-to-pmtu

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.

jmperez0 · 21 days ago

I'm hitting this at least once per hour since 2 days ago.

woifh · 21 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:

2026-06-21: 1     2026-07-20: 4     2026-08-04: 5
2026-06-22: 1     2026-07-21: 1     2026-08-05: 1
2026-06-26: 2     2026-07-22: 3     2026-08-06: 5
2026-07-08: 1     2026-07-23: 1     2026-08-07: 2
2026-07-11: 4     2026-07-24: 1     2026-08-08: 1
2026-07-12: 5

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:

grep -rh 'Connection closed mid-response' --include='*.jsonl' ~/.claude/projects \
  | grep -c '"isApiErrorMessage":true'

(Filtering on isApiErrorMessage matters — 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 |

# macOS: -D sets the DF bit; 1472 B payload + 28 B headers = 1500
ping -D -s 1472 -c 2 api.anthropic.com

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.

S313S · 20 days ago

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.

g33k3r-002 · 20 days ago

<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)

Evgeniy20181 · 19 days ago

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

fsevenm · 13 days ago

I also faced this issue, turns out my cloudflare warp cli. I disconnected it and the issue solved.

adamdunkels · 11 days ago

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:

> **HARD RULE:** At the start of every session, call `CronCreate` for a recurring self-ping (~15 min) into this session, and `CronDelete` it once nothing is left to babysit. Guards against the API-error-idle failure mode.

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.

Showing cached comments. Read the full discussion on GitHub ↗