"API Error: Stream idle timeout - partial response received": how to fix it
Back to the blog
Articletroubleshootingclaude codedev toolsprodutividade

"API Error: Stream idle timeout - partial response received": how to fix it

MafraNovember 7, 20266 min read

Halfway through a long answer, the CLI stops writing and returns:

API Error: Stream idle timeout - partial response received

The session stays open and the history is not lost, but the turn ended there. The error starts inside the CLI, not in your account: a stream watchdog gave up on the response because bytes stopped arriving for too long. It shows up in different situations, with different fixes, and this guide separates each one.

What does "Stream idle timeout - partial response received" mean?

It means the response started and was cut in the middle. The first bytes arrived, the stream opened, and at some point between one chunk and the next the connection went silent until the watchdog fired and aborted the turn.

This is different from No response from API, which is the wait before the first byte. Here the answer was already flowing. What you lose is the part being generated, not the conversation: your message, the files read and the tools already executed stay in the session.

Flowchart: the response was cut mid-stream, raise the watchdog threshold with CLAUDE_STREAM_IDLE_TIMEOUT_MS, which ships at 90 seconds by default; if a restart alone fixes it, you hit the keep-alive latch
From the error to the right fix, in three steps and one branch.

Why does the response get cut mid-stream?

Three causes cover almost every report, and each one needs a different fix. Identify yours before touching any config.

CauseHow you spot itWhat fixes it
Silence from the provider or the path to itcuts on long turns, sometimes on all of themraise the watchdog threshold
Proxy or gateway buffering the responsealways cuts behind a VPN, gateway or ANTHROPIC_BASE_URLtest without the proxy and tune the retry window
The CLI's own keep-alive latchthe session degrades over time and a restart fixes itrestart the session or roll back the version

I raised API_TIMEOUT_MS and nothing changed. Why?

Because API_TIMEOUT_MS is not the ceiling for a streaming response. The changelog spells out the behaviour: when the API sends no headers, the retry now waits up to API_TIMEOUT_MS, which defaults to 10 minutes. That is a deadline for getting an answer, not a clock measuring the silence between one chunk and the next.

Anyone who sees the idle timeout message and raises that number keeps hitting the same watchdog, because a different clock is the one that fired.

Which variable controls the stream watchdog?

It is CLAUDE_STREAM_IDLE_TIMEOUT_MS, which sets the streaming idle watchdog threshold and ships at 90 seconds by default. When no byte arrives inside that window, the turn is aborted and you see the partial response message.

VariableWhat it controlsDefault
CLAUDE_STREAM_IDLE_TIMEOUT_MSstreaming idle watchdog threshold90 seconds
API_TIMEOUT_MShow long the retry waits for a response with no headers10 minutes
API_FORCE_IDLE_TIMEOUT5-minute idle timeout restored by default on Vertex and Foundryactive on those providers; 0 opts out
CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACKdisables the non-streaming fallback when streaming failsoff

Mind the scope of each one: CLAUDE_STREAM_IDLE_TIMEOUT_MS is the general stream silence watchdog, while API_FORCE_IDLE_TIMEOUT touches a timeout specific to Vertex and Foundry. If you are not on those two providers, that second variable is not your lever.

For a single session, export before opening the CLI. The value is in milliseconds, so 180000 is three minutes:

export CLAUDE_STREAM_IDLE_TIMEOUT_MS=180000
claude

To make it apply to every session, use the env block in ~/.claude/settings.json:

{
  "env": {
    "CLAUDE_STREAM_IDLE_TIMEOUT_MS": "180000"
  }
}

In PowerShell the syntax is $env:CLAUDE_STREAM_IDLE_TIMEOUT_MS = "180000". After saving the file, run /status and check the Setting sources line to confirm the CLI loaded it.

Careful: raising the threshold prevents a premature abort, it does not repair a connection that dropped. If the cut always lands at the same point, with the clock near a round number, the problem is on the network path, not in the deadline.

Why does a long session get worse over time?

There is an aggravating factor in the connection pool. The changelog records the change: keep-alive is disabled after a stale connection so the retry opens a fresh socket. According to issue #100353, the code flips that switch and nothing turns it back on: the process starts opening a new connection for every request until it is restarted.

The author measured the effect in an orchestrator session with many subagents, on Linux, with the watchdog at 60 seconds:

ScenarioRequestsWatchdog abortsGaps of 40 seconds or more400 continuation errors
With the latch active~1,725131 (7.6%)66101
With the latch disabled in the binary~2,190002

Those numbers come from that report, not from a measurement of ours, and the issue is still open. The signal is in the log: run with --debug-file and look for the line that starts with Stale connection and ends with disabling keep-alive for retry. After it, the session tends to degrade until you restart.

How do you fix it when a restart alone works?

If the log shows the latch, there are three ways out, ordered by cost:

  1. Restart the long session after the first warning. That is what the issue author does, and it drops the stall rate to zero.
  2. Run a CLI version from before the keep-alive change described in the issue, where the trigger was not active yet.
  3. If you must stay on the current version, turn off the non-streaming fallback, which is what turns a stall into a resend of the whole conversation:
    export CLAUDE_CODE_DISABLE_NONSTREAMING_FALLBACK=1

Item 3 does not fix the latch. It avoids the expensive effect, which is resending 0.35 to 1.1 MB of conversation on every stall, according to the same report.

Does the error appear on requests longer than 5 minutes?

Then the limit is a different animal. A report opened on 2026-11-04 with CLI 2.1.317, updated on 2026-11-07, describes a large local model served through ANTHROPIC_BASE_URL: any request that goes past 5 minutes is aborted, with a run of Request timed out. Retrying until the attempt limit.

In that scenario the stream watchdog is not the only piece involved, and the author points to a possible idle timeout in the runtime's HTTP layer. For a local model that takes more than 5 minutes per answer, the practical move is to split the task into smaller pieces or wait for the fix, not to raise a watchdog variable.

How do you make it less likely to happen again?

  • Break long turns apart. Asking for a huge plan in a single turn is one of the scenarios that shows up in the reports.
  • Run /compact before long tasks, so the next turn has less context to sustain.
  • Test without a VPN, proxy or gateway when the error is constant, and compare against the direct API.
  • In automation, prefer short headless sessions and restart between batches.
  • Open long sessions with --debug-file, so you see the latch before you lose the afternoon.

Verboo Code is the second route for when the first one freezes mid-turn: it runs in the same terminal flow and delivers unlimited tokens, so a long turn does not hit a quota while you investigate the stream. Keeping two paths configured keeps a single provider from stopping your day.

Enjoyed this article?
Share knowledge with your network.
// Read also

Related articles