Table of contents
- 1. First thing to do — your output has not been thrown away
- 2. The official definitions — four "cut off mid-response" messages
- 3. v2.1.227 renamed it from "closed" to "lost"
- 4. Why it is not retried automatically
- 5. Where the break happens — three layers
- 6. What to try now — an isolation checklist
- 7. Tuning the timers and retries with environment variables
- 8. How to tell it apart from similar messages
- 9. Real reports — when ECONNRESET will not stop
- 10. What is confirmed and what is not
- FAQ
When you give Claude Code a longer job, it can suddenly stop partway through the response with this.
API Error: Connection lost mid-response. The response above may be incomplete.
Search that exact string and, oddly, very little comes back. The reason is plain: this is a fairly new name. The official Claude Code error reference says it in so many words — "Before v2.1.227, Connection lost mid-response appeared as Connection closed mid-response". The underlying event has been around for a while; only the word on screen changed from closed to lost. Because the existing material online is written under the old name, anyone searching the new one finds nothing.
Starting from that rename, this article lays out (1) what the message precisely means, (2) what to do right now in front of the screen, (3) why it is not retried automatically, (4) how to isolate which layer is breaking, (5) how to tune it with environment variables and (6) how to tell it apart from the very similar messages, using only the official documentation and public issues. Where inference enters, it carries a confidence label.
What already reached the screen has not been discarded. The official guidance is that replying continue resumes from the last block that completed.
Before v2.1.227 the display read Connection closed mid-response. Material written under the old name still applies unchanged.
What to do changes with where the break is: your machine, the path, or the server side. There are reports of raw HTTPS going through while only Claude Code drops.
1. First thing to do — your output has not been thrown away
Before any fix, let us settle the point that is misread most often. Even when this message appears, everything that had already streamed to the screen is kept. It is not discarded.
The official error reference explains the family of messages ending in "The response above may be incomplete." like this — if streaming fails after Claude has completed one text block or tool call, re-sending the request could execute the same tool call twice, so Claude Code keeps what completed and attaches this note instead of throwing the turn away.
So there are only three things to do.
Claude Code keeps every block that completed but drops the last block that was still in progress when the turn ended. What is missing is usually the closing few sentences, or the last tool call.
continueThis is the official recovery step itself. It carries on from the last completed block. Do not re-issue the instruction from the top — that runs operations which already executed a second time.
If the break landed in the middle of a file write or a command run, the transcript on screen is the record of how far it got. Look at the real state with git status before moving on.
-p runs, the Agent SDK and cloud sessions, when the interrupted response is text only and contains no tool call, Claude Code prompts Claude for the continuation itself — up to three times in a row. This note appears only once those continuations are used up. Subagents continue automatically in the same way.
2. The official definitions — four "cut off mid-response" messages
The first thing to grasp is that this wording is a note Claude Code writes itself, not the body of an error response returned by the API. That is why, for the same experience of being cut off, Claude Code varies the closing phrase by cause. The official reference lists these four.
API Error: Connection lost mid-response. The response above may be incomplete.
API Error: Your computer went to sleep mid-response. The response above may be incomplete.
API Error: The response stopped arriving. The response above may be incomplete.
The official gloss is one line — the connection was lost. The stream was flowing normally, but the connection carrying it disappeared.
An overloaded or 5xx response arrived mid-stream. Per the official docs this display itself dates from v2.1.199; before that, partial output was discarded and the whole turn was treated as an error.
When Claude Code detects that the machine slept during the response. After waking it treats the connection as broken and stops reading.
The connection stays open but data stops coming, and the stream watchdog gives up. A stall rather than a disconnect, with a different cause and a different fix.
Start by reading precisely which of the four you got. The experience of being cut off looks identical in all of them, but Claude Code has already isolated the cause and chosen the wording accordingly. If it says lost, the verdict is that the connection was lost — not that the server returned a 5xx, and not that something timed out.
3. v2.1.227 renamed it from "closed" to "lost"
This is the centre of the article. Right after listing the four explanations, the official error reference places this note.
"Before v2.1.227,Connection lost mid-responseappeared asConnection closed mid-response, andThe response stopped arrivingappeared asResponse stalled mid-stream."
— Claude Code official error reference
So two strings were swapped at the same moment. Laid out as a table, the correspondence is this.
| Display before v2.1.227 | Display today | Meaning (official) |
|---|---|---|
Connection closed mid-response |
Connection lost mid-response |
The connection was lost |
Response stalled mid-stream |
The response stopped arriving |
The connection stayed open but data stopped arriving |
Connection closed while thinking, before producing a response |
Connection lost before a response was produced |
It broke before a single character of output (no partial output) |
Response stalled while thinking, before producing a response |
The response stalled before a response was produced |
It stopped with the connection still open, before a single character of output |
Note that the third row is a different thing from the message in this article. mid-response means it broke after some output had appeared, while before a response was produced means it broke before a single character — renamed in the same batch, but different in meaning and in what happens next. The next section covers that.
What changes once you know about the rename
There are three practical effects.
Search for "Connection closed mid-response" and GitHub issues and write-ups appear at once. It is the same event, so nothing needs re-interpreting.
If it says lost, that Claude Code is v2.1.227 or later. If it says closed, it is older than that.
Because the same phenomenon is reported under two names, an issue search has to use both strings or existing reports get missed.
⚠️ Before v2.1.222 the notice itself may be false. The official error reference states plainly that "Claude Code before v2.1.222 also showed this notice when the connection dropped or stalled after the response had already completed, reporting the turn as an error even though the response was complete". In other words, on older builds the error shows even though all of the output arrived. If claude --version is lower than 2.1.222, update before you start isolating anything — the error you are looking at may not exist.
4. Why it is not retried automatically
Claude Code is not doing nothing. Per "Automatic retries" in the official reference, transient failures are retried automatically with exponential backoff, up to ten times. So when this message does appear, it means Claude Code judged that retrying here would be wrong.
The branch turns on exactly one thing: whether Claude had already completed something.
If the connection drops before Claude has completed any part of the response, thinking included, Claude Code re-sends the request on the same backoff and the turn continues. That holds even if text had begun streaming.
If thinking has finished but neither text nor a tool call has started, it re-sends at most twice at a short interval, and if it keeps dropping it ends the turn with Connection lost before a response was produced.
If it breaks after one text block or tool call has completed (or started after thinking), Claude Code does not re-send the request. Doing so could execute the same tool call twice.
Instead it keeps what completed, executes the tool calls that completed and carries the turn on from their results. Then it prints this note.
The design looks inconvenient, but it errs on the safe side. Were it to re-send automatically, operations with side effects — writing a file, running a command — could run twice on every disconnect. That is why the official guidance is continue rather than a re-send — it is the only route that does not redo work already finished.
What appears on screen during a retry
While a retry is running, a countdown appears beside the spinner: Retrying in Ns · attempt x/y. The label starts as API error, but from v2.1.198 the third attempt onward switches to the specific reason (if CLAUDE_CODE_MAX_RETRIES is under 3, it switches on the final attempt).
Separately, if the request is alive but no data arrives for 20 seconds, a banner appears while nothing has failed yet: Waiting for API response · will retry in … · check your network. This is a display meaning nothing has failed so far, and the countdown runs to the point at which Claude Code would abandon the stalled connection. Per the official docs this threshold was 10 seconds before v2.1.185, with different wording.
5. Where the break happens — three layers
Being told only that the connection was lost does not settle what to do. There are three broad places it can break, and each is verified differently.
A Wi-Fi handoff, a momentary drop on a mobile line, sleep, a VPN client reconnecting.
How to check: does it reproduce on a wired connection or a different line? If sleep is the cause a dedicated wording appears, which settles it.
Corporate proxies, TLS inspection, LLM gateways, VPNs. Appliances that treat a long-held stream as idle and cut it are not rare.
How to check: does it reproduce with HTTPS_PROXY unset? Confirm the proxy line in /status.
An incident on the service side, or a reused connection that was in fact already dead. The signature is that it keeps dropping even though your line is healthy.
How to check: look at status.claude.com. If it reproduces the same way on several lines, it is not a purely local problem.
Stale connection — reloaded rotated mTLS client material appears in the claude --debug log.
6. What to try now — an isolation checklist
Ordered from the top by largest effect for least effort. Check whether it still reproduces after each one.
| # | What to do | What it is for |
|---|---|---|
| 1 | Reply continue | Stop the loss becoming permanent. Faster than starting over, with no risk of double execution |
| 2 | Update Claude Code to the latest build | Connection behaviour changes with the version. v2.1.198 fixed a problem where a short network blip mid-response interrupted the turn |
| 3 | Split one turn into smaller ones | Split "read a pile of files and write a report" into reading and writing. Reduce the time a stream is held open at all |
| 4 | Reproduce with the VPN and proxy switched off | Isolates layer 2. If turning them off fixes it, suspect an idle cut on the path |
| 5 | Reproduce on a different line | Isolates layer 1 from layer 3. If several lines behave the same, it is not a purely local problem |
| 6 | Review the sleep settings | If your screen goes dark during a long response, the connection may break before the dedicated wording can appear |
| 7 | Look at status.claude.com | Confirms layer 3. On a 529, Claude Code prints this hostname on screen itself |
| 8 | Record a session with claude --debug | The log lands in ~/.claude/debug/<session-id>.txt. Attach it when you file a report |
| 9 | Check whether you are on a SOCKS proxy | The official documentation states that SOCKS proxies are unsupported. If you use one, take a different route |
7. Tuning the timers and retries with environment variables
Claude Code holds four independent timers for abandoning a stream that has gone quiet. The list given in the official network configuration documentation is this.
| Timer | Condition for giving up | Default timeout |
|---|---|---|
| First-byte deadline | Not one response header arrives after sending | 180s on the direct API, 300s otherwise (plus 1s per 32KB of request body) |
| Event-level watchdog | Not one response event can be parsed | 300s (active on every provider) |
| Byte-level watchdog | No bytes arrive at all, SSE keep-alive pings included | 180s on the direct API, 300s otherwise |
| Body idle timeout | No bytes for five minutes | 5 minutes (for providers other than the direct API) |
That said, what these timers give up on generally lands on the silence wording — a different message from this article's. It is set out here because you need the defaults in order to tell the two apart, not because "lost appeared, so let us extend a timer". In an environment with long silences behind a proxy, changing these values does change the stall symptom.
On the retry side, these variables apply.
| Environment variable | Default | Effect |
|---|---|---|
CLAUDE_CODE_MAX_RETRIES |
10 | How many retries. From v2.1.186 the ceiling is 15. In scripts the recommended use is to lower it and fail fast |
CLAUDE_CODE_RETRY_WATCHDOG |
unset | For unattended sessions such as CI. Set to 1 it retries 429 and 529 indefinitely, and from v2.1.199 it also raises the default count for transient errors including disconnects to 300 |
API_TIMEOUT_MS |
600000 | Timeout per request (milliseconds, so 10 minutes). Raise it on slow lines or behind a proxy |
CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS |
unset | Timeout for the byte watchdog alone. Clamped between 10 seconds and 30 minutes |
CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS |
unset | Sets the deadline to the first byte directly. Available from v2.1.242 |
CLAUDE_CODE_MAX_RETRIES helps the failure that drops before any output appears; it does nothing for a break that happened mid-response. What does help is making each turn shorter.
8. How to tell it apart from similar messages
This may be the most useful part for readers. The experience of stopping partway is shared, but the wording Claude Code prints differs, and so do the cause and the fix. Here it is, mapped onto the existing articles on this site.
| Wording on screen | What is happening | Where to read |
|---|---|---|
Connection lost mid-response |
Output had appeared and then the connection was lost | This article |
Connection closed mid-response |
The old name for the same event (before v2.1.227) | the closed article, collecting reports from the old-name era |
The response stopped arrivingold: Response stalled mid-stream |
The connection is alive but has gone silent, and a timer gave up | the stalled article (watch for the chain with a repetition loop) |
Server error mid-response |
Mid-stream, the server side returned a 5xx or overloaded | the 529 and 500 article |
Your computer went to sleep mid-response |
Claude Code detected that the machine slept during the response | review the power and sleep settings (section 6 of this article) |
Connection lost before a response was produced |
It broke before a single character appeared (no partial output) | a case that is retried. Section 4 of this article |
Unable to connect and SSL certificate errors |
It is not connecting in the first place | the network and proxy article |
court or invoke tags appear in the body |
Not networking — the tool call is not being executed | the court tag article |
The biggest branch is whether any response appeared on screen at all. If not a single character came through, the thing to suspect becomes the connection or the configuration (proxy, certificates, firewall). If output came partway, that is proof the connection was working, so moving on to this article's isolation is more correct than changing settings.
The second branch is disconnect versus silence
Whether the connection was lost or fell quiet while still open flips the next move completely.
Suspect the path and connection reuse. Extending the timeout values is pointless — nothing ran out of time; the connection itself is gone.
This is where timers matter. Tuning CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS and the like has room to help, and a model going quiet for a long stretch is also worth suspecting.
9. Real reports — when ECONNRESET will not stop
The nastiest pattern is only Claude Code dropping while the local line is perfectly healthy. Two public issues carry a considerable amount of verification work. Both are reported under this article's new name or include the wording from the version just before it.
The reporter writes that Connection dropped (ECONNRESET) · Retrying in 17s · attempt 6/10 is followed by API Error: Connection lost mid-response.. On top of that, a 60KB POST via curl and a POST of the same size via plain Node.js https.request both completed normally, and a long-running SSE from another host did not break either.
MTU checks, Winsock LSP checks, reproduction on a minimal configuration and reproduction on two unrelated networks are all done, and it remains unresolved. Issue #86473 is marked as a duplicate yet stays open.
This one is Connection dropped (ECONNRESET) · Retrying in 0s · attempt 4/10. The reporter writes that after fully uninstalling security software and ruling out VPN filters, the proxy and IPv6, and resetting Winsock, it reproduced identically on three networks: office Wi-Fi, home Wi-Fi and phone tethering.
The contrast offered is that the claude.ai chat works without trouble on the same machine with the same account. Issue #85979 is likewise still open (stale).
Even so, there is something practical to take from the two. "ping works" and "curl works" are not evidence that this error will not occur. Traffic that holds one connection open for minutes of streaming is not in the same situation as a short request. Rather than pouring time into inspecting the local network, splitting the turn is the easier way to lower how often it reproduces.
10. What is confirmed and what is not
To avoid misreading, here is what can be confirmed officially, kept separate from what cannot.
- This wording is formally documented in the official error reference, and it means the connection was lost
- Before v2.1.227 it appeared as
Connection closed mid-response(a rename of the same thing) - Output that already streamed is kept deliberately (because a re-send risks double execution)
- The recovery step is to reply
continue - A break before output appears is retried automatically (up to ten times, exponential backoff)
- Non-interactive sessions and subagents continue on their own (from v2.1.246 and v2.1.257 respectively)
- Raw HTTPS is healthy while only the CLI dies with ECONNRESET (reported in #86473 and #85979)
- The contrast that the browser version is fine on the same machine and account (reported in #85979)
- The possibility that a connection-reuse bug is involved (support's explanation, as quoted by the reporter)
- A mention that there were server-side incidents at particular times (again via the reporter)
- An official explanation of the cause from Anthropic (neither issue above has a public answer)
- The reason for the rename. No wording change is recorded in the CHANGELOG
- #86473 and #85979 are both still open
In short, the symptom, the meaning and the recovery step are officially documented, while no official explanation of why it breaks has been published. What reliably works in that situation is not identifying the cause but operating so that a break costs little — split turns short, run operations with side effects while checking the state, and keep the version current. Those three help whatever the cause turns out to be.
FAQ
Q1. Are "Connection lost mid-response" and "Connection closed mid-response" different errors?
They are the same thing. As the official error reference states explicitly, before v2.1.227 the same event was displayed as Connection closed mid-response. A changed display does not mean a new kind of failure has appeared. Material written under the old name can still be used as it stands.
Q2. Is the output up to that point lost?
It is not. Every block Claude completed is kept. The only thing discarded is the last block that was still in progress when the turn ended. Claude Code deliberately attaches this note rather than re-sending, because a re-send risks executing the same tool call twice.
Q3. What do I reply to resume from where it stopped?
Reply continue. That is the recovery step the official error reference gives, and it carries on from the last completed block. Re-issuing the instruction from the top risks duplicating operations that have already run.
Q4. Will raising the retry count fix it?
It will not. As section 4 explains, this is the note for a situation where Claude Code is deliberately avoiding a retry. CLAUDE_CODE_MAX_RETRIES (default 10, ceiling 15 from v2.1.186) helps the failure that drops before output appears. What helps here is making each turn shorter.
Q5. Is it the same with -p or in CI (non-interactive runs)?
The behaviour differs. Per the official reference, in a non-interactive session, when the interrupted response is text only and contains no tool call, Claude Code prompts for the continuation itself — up to three times in a row. This note appears once those are used up. Before v2.1.246 it ended the turn on the first disconnect. If you use --output-format json, this message lands in the result field.
Q6. It appears in subagents (Task) too.
Subagents continue automatically in the same way. If the interrupted response is text only, Claude Code prompts the subagent for the continuation, and only once the continuations are used up does this note become the final message. Before v2.1.257 it printed the note on the first disconnect.
Q7. Is my own network to blame?
It may be, but not necessarily only that. The reporter on Issue #86473 showed that POSTs of the same size via curl and via plain Node.js both complete, and reports that only the CLI drops. First check whether it reproduces with the VPN and proxy switched off, then try a different line. If neither changes anything, it is not a purely local problem.
Q8. Will longer timeouts reduce it?
For this message, do not expect that. The verdict is that the connection itself was lost, not that time ran out. Extending timers such as CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS helps with The response stopped arriving, the symptom where the connection is alive but goes silent.
Q9. How do I check which version I am on?
Run claude --version. If the screen says lost you are on v2.1.227 or later; if it says closed, you are on something earlier. Connection behaviour has changed across versions, and the official CHANGELOG records a fix in v2.1.198 for a short network blip mid-response interrupting the turn. Updating is well worth trying first, but it is no guarantee of a cure — both of the issues cited above are reports on versions newer than that.
Q10. It happens constantly on a corporate network. Which settings should I look at?
The official network configuration documentation covers the essentials. Three points: first, SOCKS proxies are unsupported, so do not use one; second, put the proxy variables in the env block of ~/.claude/settings.json rather than exporting them from the shell (background agents do not inherit the shell environment); third, if you use mTLS, watch out for certificate rotation. Whether the settings were read can be confirmed in the claude --debug log or in the /status display.
Related articles
- API Error: Connection closed mid-response — Causes and Fixes in Claude Code
- Claude Code repeats "court" infinitely and halts with Response stalled mid-stream: causes and fixes
- Claude Code Network, Proxy and TLS Certificate Errors (Unable to connect): Causes and Fixes
- Claude Code "529 Overloaded" and "500" Server Errors: Causes and Fixes
- Claude Code Prints "court" and Raw invoke Tags — Why Tool Calls Do Not Run, and How to Fix It
- Claude Code Common Errors and Fixes — The Complete Reference
Primary sources consulted
- Claude Code — Error reference (official documentation): the definitions of the four strings, the v2.1.227 rename, recovery via
continue, the Automatic retries branch, environment variables - Claude Code — Enterprise network configuration (official documentation): the four stream watchdog timers and their defaults, proxy configuration, SOCKS being unsupported, the mTLS reload
- anthropics/claude-code — CHANGELOG (official): the v2.1.198 fix for a short network blip mid-response interrupting the turn
- Issue #86473 — ECONNRESET / Connection lost mid-response (v2.1.229 on Windows 11)
- Issue #85979 — ECONNRESET continuing on v2.1.228 (Windows 11)
- Claude service status (official status page)