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.

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

What already reached the screen has not been discarded. The official guidance is that replying continue resumes from the last block that completed.

2. About the name
A renamed closed

Before v2.1.227 the display read Connection closed mid-response. Material written under the old name still applies unchanged.

3. If it repeats
Isolate the layer

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.

Step 1
Read the output that remains

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.

Step 2
Reply continue

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

Step 3
Check operations with side effects

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.

Outside interactive sessions it continues on its own. Per the official reference, in non-interactive sessions such as -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: Server error mid-response. The response above may be incomplete.
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.
This article's subject
Connection lost mid-response

The official gloss is one line — the connection was lost. The stream was flowing normally, but the connection carrying it disappeared.

A server-side failure
Server error mid-response

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.

Something local
Your computer went to sleep mid-response

When Claude Code detects that the machine slept during the response. After waking it treats the connection as broken and stops reading.

Silence, not a disconnect
The response stopped arriving

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-response appeared as Connection closed mid-response, and The response stopped arriving appeared as Response 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.

Material under the old name still works

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.

It tells you roughly which version you are on

If it says lost, that Claude Code is v2.1.227 or later. If it says closed, it is older than that.

It matters when judging duplicate issues

Because the same phenomenon is reported under two names, an issue search has to use both strings or existing reports get missed.

🟡 It is not in the CHANGELOG. The rename is written only on the documentation side; as far as I could verify, the v2.1.227 entry in the official CHANGELOG records no wording change. From a user's point of view the word simply changed one day. Do not read the changed display as a different, newly appeared error.

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

Retried
A break before anything completed

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.

Not retried ← this article
A break after a block completed

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.

Layer 1
Your machine and your line

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.

Layer 2
The path (proxies and gateways)

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.

Layer 3
The server side and connection reuse

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.

An easily missed fourth possibility — mTLS certificate rotation. If you use client certificates in a corporate environment, replacing the certificate and the key causes connection-level errors (connection resets, TLS handshake failures). Per the official network configuration documentation, Claude Code reloads both files on such connection errors and retries with the new pair. That reload is v2.1.232 and later behaviour, though; before it, the old pair was held until a restart or a settings reload. You can confirm it by whether 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
1Reply continueStop the loss becoming permanent. Faster than starting over, with no risk of double execution
2Update Claude Code to the latest buildConnection behaviour changes with the version. v2.1.198 fixed a problem where a short network blip mid-response interrupted the turn
3Split one turn into smaller onesSplit "read a pile of files and write a report" into reading and writing. Reduce the time a stream is held open at all
4Reproduce with the VPN and proxy switched offIsolates layer 2. If turning them off fixes it, suspect an idle cut on the path
5Reproduce on a different lineIsolates layer 1 from layer 3. If several lines behave the same, it is not a purely local problem
6Review the sleep settingsIf your screen goes dark during a long response, the connection may break before the dedicated wording can appear
7Look at status.claude.comConfirms layer 3. On a 529, Claude Code prints this hostname on screen itself
8Record a session with claude --debugThe log lands in ~/.claude/debug/<session-id>.txt. Attach it when you file a report
9Check whether you are on a SOCKS proxyThe official documentation states that SOCKS proxies are unsupported. If you use one, take a different route
"Claude in the browser is fine" proves nothing here. The claude.ai chat and the Claude Code CLI open connections differently and hold a single connection open for different lengths of time. One being fine while only the other drops is entirely possible (in fact Issue #85979, discussed below, reports exactly that situation). It is better not to conclude that the account is fine, so it must be a configuration problem.

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
⚠️ Raising the retry count will not reduce this message. As section 4 showed, it is the note printed exactly where Claude Code is deliberately avoiding a retry. Raising 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 arriving
old: 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.

If it is a disconnect (lost)

Suspect the path and connection reuse. Extending the timeout values is pointless — nothing ran out of time; the connection itself is gone.

If it is silence (stopped arriving)

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.

Issue #86473 (v2.1.229 on Windows 11)
Raw HTTPS goes through; only the CLI breaks

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.

Issue #85979 (v2.1.228 on Windows 11)
The browser version is fine on the same machine

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

🟡 On the confidence of this section. Both of the above are individual reports, not an official explanation of the cause from Anthropic. In #85979 the reporter writes that support said the bug around reusing stale connections should be fixed in v2.1.227 and later, but that it still reproduced after updating — that is the reporter quoting an exchange with support, not a published official position. The same goes for the two incident windows mentioned in #86473: that too is what the reporter says support told them. Please do not read any of it as an event with settled reproduction conditions.

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.

✅ Confirmed officially
  • 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)
🟡 Reported but unconfirmed
  • 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)
🔴 Unpublished as of writing
  • 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

Primary sources consulted