Claude Code 报错 “Stream idle timeout – no chunks received”:调大哪个变量、哪些做法没用(实测)
“Stream idle timeout - no chunks received” 是 Claude Code 的看门狗在掐断沉默的流。调大 CLAUDE_STREAM_IDLE_TIMEOUT_MS(文档建议 1800000);低于 300000 会被抬到 300 秒。用沉默的模拟服务器实测,并写出我实际看到的报错文字。

先说结论:API Error: Stream idle timeout - no chunks received 不是 Anthropic 服务器的错误,而是 Claude Code 自己的看门狗(watchdog)把一条沉默了的响应流掐断了。把 CLAUDE_STREAM_IDLE_TIMEOUT_MS 调大;如果你不知道最长停顿有多久,就从 1800000(30 分钟)开始,这是 Anthropic 的 Claude apps gateway 文档给的起始值(该文档针对网关部署)。我用一个会突然沉默的模拟服务器测了这些计时器。有两件事出乎意料:低于 300000 的值会被悄悄抬到 300 秒;在 Claude Code 2.1.312 和 2.1.319 上我看到的报错文字和文档里写的不一样。详情和日志在下面。
这个报错是什么意思
Claude Code 以流式方式接收模型的回答。为了不在一条已经死掉的连接上永远卡住,它运行了几个计时器,一旦流不再送数据就中止。按 Anthropic 的网络配置文档,一共有四个:
| 计时器 | 什么时候中止 | 默认值 |
|---|---|---|
| — | — | — |
| 首字节期限 | 请求发出后没有收到响应头(直连 API 和部分其他连接) | 直连 Anthropic API 为 180 秒 |
| 事件级看门狗 | 没有可解析的响应事件 | 300 秒 |
| 字节级看门狗 | 一个字节都没到,心跳 ping 也算 | 直连 API 180 秒;经自定义 ANTHROPIC_BASE_URL 为 300 秒 |
| 正文空闲超时 | 5 分钟没有字节(直连 API 以外的提供方) | 5 分钟 |
这种情况在文档里的报错文字是 API Error: Stream idle timeout - no chunks received,列在 Anthropic 的报错参考里。文档给出的典型原因是路径上有网关或代理:模型长时间思考时,只有保活 ping 在流动。
我让流沉默时看到了什么(实测)
我写了一个很小的模拟服务器:对 Claude Code 的请求返回 HTTP 200,发出开头的 message_start 事件,然后一声不吭。我用 claude -p "say hi" 去连它,ANTHROPIC_BASE_URL 指向模拟服务器,API key 是编的:
| 设置 | 发生了什么 |
|---|---|
| — | — |
CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS=10000 | 第二次请求恰好在第一次之后 10 秒;最终输出 API Error: stream idle: no bytes for 10000ms(2.1.312 和 2.1.319) |
| 同上,但模拟服务器先发了一些文字 | 结果相同:10 秒后重试,-p 模式下最后还是同一句 API Error: stream idle: no bytes for 10000ms |
CLAUDE_ENABLE_BYTE_WATCHDOG=0 加 CLAUDE_STREAM_IDLE_TIMEOUT_MS=10000 | 10 秒时没有失败。每 300 秒一次新请求;两次尝试(600 秒)之后以 Request timed out 结束 |
只在项目 .claude/settings.json 的 env 里设 CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS=15000 | 恰好 15 秒后重试,说明走设置文件这条路是有效的 |
三点实话。第一,我没有复现文档里写的原文 Stream idle timeout - no chunks received;在这些版本上,字节级看门狗打印的是 stream idle: no bytes for 10000ms。你看到的文字可能随版本和连接类型而不同。第二,我的模拟服务器不是真实的 API。第三,我全程用的是非交互的 -p 模式,所以没看到交互界面里的“response above may be incomplete”提示。
解法:把超时调大
文档的建议是把 CLAUDE_STREAM_IDLE_TIMEOUT_MS 调到能覆盖你最长的停顿。写进 shell 配置文件:
export CLAUDE_STREAM_IDLE_TIMEOUT_MS=1800000
或写进设置文件的 env 块(我的测试用的是同一种机制,只是变量换成了字节级那个):
{"env": {"CLAUDE_STREAM_IDLE_TIMEOUT_MS": "1800000"}}
设置文件放在哪,见 Claude Code settings.json 路径。文档里的规则:
CLAUDE_STREAM_IDLE_TIMEOUT_MS同时设置事件级和字节级的超时。低于 300000(5 分钟)的值会被 Claude Code 抬到 300000,字节级的上限是 30 分钟。我确认了抬高这一点:第二项测试里 10000 实际按 300 秒起作用。CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS只改字节级看门狗,范围 10 秒到 30 分钟,需要 Claude Code 2.1.210 或更新版本。API_TIMEOUT_MS限制的是等响应头的时间,不是流之后可以沉默多久,所以它不是这里的解法。- 超时调长也意味着,真正死掉的连接要更久才会被发现。
看起来管用其实不管用的做法
- 调低这个变量不会让它更快失败。 因为有 300000 的下限,设成 60000 应该会让事件级看门狗仍然是 300 秒(文档这么说,我的 10000 测试也是这个表现)。想更快失败,用字节级变量(最低 10 秒)。
- 把看门狗关掉不是解法。 文档说
CLAUDE_ENABLE_STREAM_WATCHDOG=0和CLAUDE_ENABLE_BYTE_WATCHDOG=0会关掉计时器,之后死连接就没有提前退出的机会了。除了上面两个超时,我没有测真正的卡死。 - 代理自己也有超时。 如果你的网关或反向代理关闭空闲连接比 Claude Code 更早,只调大 Claude Code 的值没有任何作用。代理的超时也要调。
检查网络这一侧
文档里最常见的嫌疑是:模型思考期间占着连接的网关、代理或 VPN。一个 GitHub issue(anthropics/claude-code #70217)描述了一位用户的 ISP 的 NAT 会丢掉空闲几秒的连接;我没有验证这个说法。如果报错只在某一个网络下出现,改计时器之前先换个网络测一下。
相关报错
这个报错不同于 “streaming response ended before any complete data”、529 overloaded 和 “unable to connect to API”。更多见 Claude Code 报错清单。
常见问题
看到这个报错,是不是 Anthropic 的 API 挂了?
不一定。这个报错来自 Claude Code 内部的计时器。它告诉你流沉默的时间超过了计时器允许的长度,不管原因是什么。
报错之后我该怎么做?
文档说,在交互会话里回复 continue;Claude Code 会保留所有已完成的块,丢弃被打断的最后一块。这一条我没有测。
值调大会拖慢正常使用吗?
不会。计时器只在流沉默时才起作用,它决定的是 Claude Code 等多久才放弃。
来源与测试说明
- Anthropic 文档:网络配置的 “Streaming idle watchdogs”(
code.claude.com/docs/en/network-config);报错参考(code.claude.com/docs/en/errors);环境变量(code.claude.com/docs/en/env-vars)。 - 自己实测:Linux 上的 Claude Code 2.1.312 和 2.1.319,对着一个会沉默的模拟服务器,测了
CLAUDE_BYTE_STREAM_IDLE_TIMEOUT_MS、关掉字节看门狗后的CLAUDE_STREAM_IDLE_TIMEOUT_MS,以及设置文件的env条目。 - 没测:真实的 Anthropic API、网关、Bedrock、交互模式、文档里的原文报错、
continue的行为。