You are working in Claude Code and, partway through a response, everything stops with this:

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

It might hit while a long report is being written, while several files are being read, or right after you start a fresh session. The timing varies and there is no reliable way to reproduce it. This is not a problem with how you wrote your prompt — it is a transport-layer event: the connection carrying the streamed response was closed while the response was still arriving.

And there is one fact that matters more than any of the theories. Most of the public reports of this error come from versions released before Claude Code changed how it handles dropped connections. Follow the official changelog and you will find five separate connection and retry fixes from 2.1.179 onward. This article works only from the official error reference, the official changelog, and real issues backed by packet captures, and covers (1) what the message precisely means, (2) what to do right now, (3) where the connection is actually closing, (4) what changed between versions, and (5) how to design around it as a developer.

The short version
1. Right now
The output on screen is still there

Everything that already streamed is intact. The documented way to resume is to reply continue.

2. Highest-value fix
Update Claude Code

2.1.198 stopped brief network drops from killing the turn; 2.1.214 stopped retries from reusing a dead connection.

3. If it persists
Isolate the layer

Your machine, the path (proxy/VPN), or the server side — each needs a different response. Server-initiated closes have been reported.

1. What the message actually means — the official definition

First, this text is a notice Claude Code writes itself — it is not an error response returned by the API. The official Claude Code error reference explains the whole family of messages that end in "The response above may be incomplete." like this: when a streaming response fails after Claude has already produced visible output, re-sending the request could run the same tool calls twice, so Claude Code keeps what already streamed and appends this notice instead of discarding the turn.

The ending of the sentence is then the name of the cause. The reference lists three variants.

This article
Connection closed mid-response

The official explanation is one line: the connection dropped. The stream was running, but the connection carrying it closed.

Covered separately
Response stalled mid-stream

Officially: the stream stopped sending data. The connection is still alive but goes silent. Stalled, not severed.

Server-side failure
Server error mid-response

An overloaded or 5xx error mid-stream. Per the docs, this variant requires v2.1.199 or later; before that the partial output was discarded and the whole turn reported as an error.

All three in one line. Connection closed means the link was severed; Response stalled means it went silent; Server error means the server fell over. They all look like "it stopped halfway," but each happened at a different point in the transport.

The reference also spells out one more behaviour worth knowing. If the same failure happens before any visible output, Claude Code retries the request instead of finalizing it. In other words, the fact that you are reading this message means output had already appeared — so re-sending could duplicate side effects, and Claude Code deliberately did not auto-retry. Seeing the error does not mean nothing was attempted.

2. Do this first — nothing has been lost

Before you panic and re-issue the same instruction, work through these in order.

STEP 1 — Read what streamed

As the docs say, nothing has been lost. What is missing is most likely just the final sentences or the last tool call.

STEP 2 — Reply continue

The recovery step named in the official error reference. Have Claude pick up where it stopped instead of starting over.

STEP 3 — Check for side effects

If it dropped during file edits or command execution, some of it may already have run. Look at the real state with git status before continuing.

STEP 4 — If it repeats, check your version

Several times in one session means you should check the version before anything else. This area has been fixed repeatedly.

Do not skip step 3. When the docs say re-sending "could run the same tool calls twice," the flip side is that some tools may already have executed at the moment of the drop. If it happened mid-way through writing files, committing, or deploying, looking at the actual state first is the fastest route back.

3. Why it drops — three layers where the connection can close

"The connection dropped" is not actionable on its own, so it helps to separate the places where a close can originate. The reports fall into three layers.

Layer 1 — your machine
Device, link, sleep

A Wi-Fi blip, a mobile handover, waking from sleep. The official changelog even has a fix for "streaming requests failing after the machine wakes from sleep" (2.1.186), so this layer is real.

What helps: a wired or stable link; don't let the machine sleep during long work.

Layer 2 — the path
Proxies, VPNs, idle timeouts

The official Claude API error documentation states that some networks drop idle connections after a variable period, and recommends setting a TCP keep-alive. Corporate proxies and VPNs are prone to exactly this.

What helps: temporarily bypass the proxy/VPN and see whether it still reproduces.

Layer 3 — the server side
A server-initiated close

There is packet-level evidence of the connection being closed from the server side while the stream was in flight (next section). Nothing you tidy up locally prevents that.

What helps: client-side retry behaviour — which is why updating works.

Indeed, the reporter of GitHub issue #69415 ([BUG] API Error: Connection closed mid-response ==> frequent enough to make Claude Code unusable for any task, opened 18 June 2026 and still open at the time of writing) describes Windows 11 with WSL2, a direct connection with no corporate firewall and no proxy, on Claude Code 2.1.181. The claim, in other words, is that it happens even with layers 1 and 2 ruled out. The issue carries the labels area:networking, platform:vscode and platform:wsl.

The same reporter writes that on the same machine and the same network, other AI assistants (GitHub Copilot, Cursor and others) complete the identical task. That is a comparison made by a user, however — not a determination of cause by Anthropic, and the distinction is worth keeping.

Another report describes clearly different conditions. Issue #69336 (occurs immediately in new context window, opened 18 June 2026 and open, Claude Code 2.1.173, Debian 13, a self-hosted Claude Agent SDK) reports that the frequency rises after context summarization (compact) runs. It carries area:agent-sdk, area:api and platform:linux, and starting a brand-new conversation is described as a temporary workaround. Issue #69517 (in Claude Cowork, 19 June 2026, macOS, 2.1.183) was closed as a duplicate.

4. What packet captures showed: a server-initiated close

The deepest first-hand investigation of this class of error is issue #67766 (opened 12 June 2026, still open). The reporter captured packets in their own environment and correlated ten incidents.

Measurements from the packet captures published in issue #67766
10 / 10
Every incident was a clean, server-initiated close (FIN). Never an RST from a middlebox, never a client-side close
3–105 ms
Time from the FIN arriving to the CLI showing the error — essentially immediate
7–20 KB
Response data already delivered when the close arrived. The request body (1–2.5 MB) had been fully acknowledged seconds earlier
~20 ms
A fresh connection opened right afterwards, and the next request succeeded. The link itself was fine
200 in 23 days
Errors found in the same reporter's local session transcripts (171 distinct incidents)
87 of 171
Occurred less than five seconds after the previous API activity — that is, mid-task

Source: the packet captures and session transcripts published by the reporter of GitHub issue #67766. These are one user's measurements, not results verified by Anthropic.

The technically telling detail is that the closes were selective. According to the report, other connections to the same destination stayed alive through the event, and the one that was closed was the connection owned by the process making the request. Connections owned by two other claude processes running at the same time were untouched. A link outage would have taken all of them down; it did not.

The reporter also observed that in four of the ten incidents, batches of closes hit several pooled connections at once, and that three fired at the :54-second mark of nearby minutes (01:19:54, 01:20:54 and 01:22:54 UTC) — which they read as a sign of something running on a 60-second cycle.

🟡 How confident should you be in this section?

The message shown in issue #67766 is "API Error: The socket connection was closed unexpectedly", which is different wording from the one in this article. They cannot be declared the same bug. That said, it is currently the only publicly available packet-level evidence for the same layer of behaviour — a connection closing while a stream is in flight — so it is worth using as a working hypothesis. Note also that no explanation from Anthropic has been published on that report as of writing.

5. Check your version — the timeline of fixes

This is the most practically useful part of the article. Follow the official Claude Code changelog and you find that handling of mid-stream connection drops has been improved repeatedly. Each of the entries below is genuinely in the changelog.

v2.1.179

Partial responses are now preserved when a connection drops mid-stream. Before this you got a raw error, and the spinner could get stuck at "running tool".

v2.1.185

The stall hint became "Waiting for API response · will retry in …", and now fires after 20 seconds of silence instead of 10, so brief wobbles no longer raise a warning.

v2.1.198 ★ the key one

Fixed brief network drops mid-response aborting the turn. Transient errors such as ECONNRESET now retry with backoff instead of failing.

v2.1.199

Fixed streaming responses being discarded when an overloaded or server error arrives mid-stream. The partial is now kept with an incomplete-response notice — which is where the Server error mid-response variant comes from.

v2.1.214 ★ the key one

Keep-alive connection pooling is now disabled after a stale-connection error, so retries open a fresh socket. That speaks directly to the pattern #67766 described — a reused connection being closed.

Now line that timeline up against the versions in the reports above.

ReportVersion at the timeFixes not yet applied
#693362.1.173All of 2.1.179 / 198 / 199 / 214
#694152.1.1812.1.198 / 199 / 214 (the retry improvement and the pooling fix)
#695172.1.1832.1.198 / 199 / 214

All three predate 2.1.198, the release that absorbs transient drops through retries. So the first thing to check is your own version.

claude --version

If it is below 2.1.198, updating beats troubleshooting. The latest changelog entry at the time of writing is 2.1.220, which includes all of the fixes above.

That said, updating is not guaranteed to make it disappear. The changelog contains no entry that names "Connection closed" itself; all of the above are improvements to adjacent connection handling. Treat updating as the highest-value first move, not as a proven cure.

6. Conditions that make it more likely

These factors recur across the reports.

📄 Long responses

Reading several large files and producing a structured report — anything that keeps the stream open for a long stretch (#69415).

🗜️ Just after a compact

Reported to become more frequent after context summarization runs (#69336). Requests tend to be larger right after a summary.

📦 Very large requests

In the #67766 measurements the closed connections were carrying request bodies of 1–2.5 MB. For reference, the official Messages API request limit is 32 MB.

📡 Something in the path

Corporate proxies, VPNs, long-haul links. This is the layer the official docs describe when they mention networks that drop idle connections.

💤 Waking from sleep

Changelog 2.1.186 fixed streaming requests failing after the machine wakes from sleep. Don't let the machine nap during long jobs.

🔁 Back-to-back activity

In #67766, 87 of 171 incidents happened less than five seconds after the previous API call — a pattern idle timeouts alone do not explain.

7. Fix it now — a checklist for users

Work down the list; the cheapest moves come first.

#What to doWhy
1Reply continueThe documented recovery step. Reuses what already streamed instead of starting over.
2Run claude --version and update if it is oldGets you the 2.1.198 retry improvement and the 2.1.214 pooling fix. Do this first.
3Check for side effects (git status and similar)See whether tools partially executed before the drop. Avoids duplicate execution.
4Split the task upShorter responses mean less time exposed. Break "read every file and write a report" into stages.
5Bypass the proxy/VPN temporarily and retestIsolates layer 2. If it stops, the path is the culprit.
6Disable sleep and power saving; use a wired linkIsolates layer 1 — especially on a laptop running long jobs.
7Try a brand-new sessionThe temporary workaround reported in #69336. Sometimes effective when it spikes right after a summary.
8If it reproduces, file a report with detailsAs the official API docs advise, include the request_id (the identifier starting with req_) so it can be investigated quickly.

What not to do. Disabling TLS verification (NODE_TLS_REJECT_UNAUTHORIZED=0 and the like) because "the connection keeps dropping" targets a completely different symptom and throws away the security of your traffic. Certificate errors are a different error with a different fix.

8. For developers — preventing it in the API/SDK

If you are hitting the same class of drop through the Claude Agent SDK or your own API integration, the official Claude API error documentation gives concrete design guidance.

1. Always stream long responses

The docs warn you to use the streaming Messages API or the Message Batches API for long-running requests, especially those over 10 minutes. A large max_tokens without streaming is the shape most likely to be cut off.

2. Set a TCP keep-alive

The docs state that setting a TCP keep-alive reduces the impact of idle-connection timeouts if you are writing a direct integration. The official SDKs already set it. Check this if you rolled your own HTTP client.

3. Know what the SDK retries

The official SDKs retry transient failures — connection errors, rate limits, 5xx — twice by default with exponential backoff, honouring the retry-after header. A client option lets you change or disable it.

4. Errors after a 200 are different

The pitfall the docs call out explicitly: with SSE, an error can occur after the API has returned 200, so it does not follow the standard HTTP error path. Handle mid-stream error events separately.

5. Don't throw away the partial

Claude Code itself moved this way in 2.1.179 and 2.1.199. Keeping the blocks you received and asking for the rest costs less — in tokens and in side effects — than discarding everything and re-sending.

6. Suspect your connection pool

In 2.1.214 Claude Code changed keep-alive pooling to disable after a stale-connection error so retries open a fresh socket. It is worth checking whether your retry is grabbing the same dead connection.

For workloads where you would rather not assume an unbroken connection at all — batch processing being the obvious case — the officially recommended route is the Message Batches API, polling for results. That removes the network risk structurally rather than mitigating it.

9. Telling it apart from similar errors

Claude Code's transport errors read alike. The quickest way to separate them is by how far the request got.

MessageWhere it stoppedMain response
Connection closed mid-response (this article)Connected and streaming, then severedcontinue / update / isolate the path
Response stalled mid-streamConnection alive but silentCovered separately (watch for the repetition-loop chain)
Server error mid-responseA 5xx or overloaded error mid-streamWait and retry. See the 529/500 article
Unable to connect / SSL certificate verification failedNever connected at allProxy, corporate CA, firewall. See the connection error article
Prompt is too longRejected before sending (the network is fine)Trim the context. See the dedicated article

The biggest fork is simply whether any response appeared on screen. If not a single character came through, suspect the connection itself — configuration and path. If output appeared and then stopped, that is proof the connection worked, so stop editing settings and follow the isolation steps in this article instead.

10. Official status, and what is still unconfirmed

To avoid any confusion, here is what can be confirmed officially and what cannot.

✅ Officially confirmed
  • The message is formally documented in the official error reference, and means "the connection dropped"
  • Output that already streamed is preserved — by design
  • The recovery step is to reply continue
  • Failures before any visible output are retried automatically
  • Connection-handling fixes shipped in 2.1.179 / 198 / 199 / 214
🟡 Reported but unconfirmed
  • Servers sending a FIN mid-stream (measured in #67766 — but under a different message)
  • A 60-second sweep being involved (the reporter's own inference)
  • Spikes right after a compact (#69336)
  • Other AI assistants not failing under the same conditions (#69415 reporter's comparison)
🔴 Not provided / not published as of writing
  • An official explanation of the cause from Anthropic (no public reply on #69415, #69336 or #67766)
  • A fix entry naming "Connection closed" (that string does not appear in the changelog)
  • #69415, #69336 and #67766 are all still open

In short, the symptom and the response are officially documented, but no official explanation of why it drops has been published. Given that, operational habits beat root-cause hunting: keep turns short, verify state as you go through operations with side effects, and stay on a current version.

FAQ

Q1. When "Connection closed mid-response" appears, is the output so far lost?

No. As the official error reference makes explicit, everything that already streamed is kept. Claude Code deliberately appends the notice rather than re-sending, because re-sending could run the same tool calls twice. What is missing is most likely only the final sentences or the last tool call.

Q2. What should I reply to pick up where it stopped?

Reply continue. That is the recovery step named in the official error reference. Re-issuing your original instruction risks duplicating operations that already ran.

Q3. Are the tokens wasted?

What was generated up to the drop has been consumed. The reporter of issue #69336 notes that consumed tokens are not refunded. That is exactly why using continue — rather than starting over — matters for cost as well as time.

Q4. Is this the same thing as "Response stalled mid-stream"?

No. By the official definitions, Connection closed means "the connection dropped", while Response stalled means "the stream stopped sending data" — severed versus silent. They look similar on screen, but the stalled variant has been reported in combination with a model repetition loop, and the fix differs. See the Response stalled mid-stream article.

Q5. Is my network at fault?

It may be, but not necessarily. The reporter of issue #69415 saw it on a direct connection with no proxy and no firewall, and the packet captures in issue #67766 indicate the close was initiated from the server side. Bypass any proxy or VPN first and see whether it still reproduces; if nothing changes, it is not purely local.

Q6. Will updating Claude Code fix it?

It is the single highest-value thing to try first. The official changelog shows 2.1.198 fixing "brief network drops mid-response aborting the turn", and 2.1.214 changing keep-alive pooling to disable after a stale-connection error so retries open a fresh socket. The cluster of reports (2.1.173 to 2.1.183) all predates those. But since no changelog entry names "Connection closed" itself, updating is a likely improvement, not a guaranteed cure.

Q7. It happens constantly on long tasks. Any workaround?

Splitting the task so each response is shorter is the most reliable option. Batch jobs like "read every large file and write the report" expose the stream for a long time; separating the reading from the writing shortens that window and lowers the odds of catching a drop. Issue #69336 also reports that starting a new conversation helped temporarily.

Q8. As a developer, how do I prevent this in my own app?

The guidance in the official Claude API documentation is clear: (1) always stream long responses, and consider the Batches API beyond 10 minutes; (2) set a TCP keep-alive (the official SDKs already do); (3) with SSE, errors can arrive after a 200, so handle mid-stream error events separately; (4) on a drop, keep what you received and request the remainder. Include the request_id when you contact support.

Q9. I get the same error in Claude Cowork and the Agent SDK.

The same message has been reported there. Issue #69517 reports it in Claude Cowork (closed as a duplicate) and #69336 through a self-hosted Claude Agent SDK. It is a behaviour of the layer that handles streaming responses, so the approach is the same: resume rather than restart, stay on a current version, and design your retries.

Related articles