工具大全
踩坑实录作者:Coocon2026年10月5日4 次阅读约 10 分钟阅读

Claude Code 一直卡住、转圈没反应怎么办:后端不回时它要等 6 分钟,重试满 10 次可能卡一个多小时(实测)

先回答你搜的问题

  • 转圈不动、计时一直在涨(Clauding… (4m 34s)):Claude Code 在等后端回数据,后端一个字节都没回。用 API key 加 ANTHROPIC_BASE_URL(中转站、网关)时,它每次要等满 6 分钟才判定超时。
  • 停在 Retrying in 0s · attempt 1/10 不动:上一次已经超时,这是重发的请求又在等 6 分钟,不是死机。
  • 会卡多久:默认重试 10 次,后端一直不回的话,实测要约 69 分钟(4147.78 秒)才最终报 Request timed out。
  • 马上能做的:按 Esc 中断,再发一次。反复出现就是后端或网络的问题,先单独用 curl 测一下你的 base URL 通不通(命令见下文「实践效果」第 1 条)。
  • 想让它早点放弃:设 API_TIMEOUT_MS=60000(只能调小,调大没用)和 CLAUDE_CODE_MAX_RETRIES=2。
  • 只在长回复时卡、短问题正常:很可能是中转站把回复缓冲到生成完才返回。生成超过 6 分钟的回复会被 Claude Code 掐断重发,永远拿不到结果。换支持流式的中转,或者让任务拆小。
  • 卡在执行某条命令上(界面显示的是 Bash 而不是转圈):那是另一回事,见 Command timed out after 2m 0s。

问题背景

「Claude Code 一直卡住」是个很笼统的说法,界面上通常就是一个转圈的动词加计时,没有任何报错:

❯ 帮我把这个函数重构一下
✢ Clauding… (4m 34s)

等久了,有时会变成这样,然后又不动了:

✻ API error · Retrying in 0s · attempt 1/10

这时你无法判断它是在干活、在等网络,还是真的死了。官方文档在 Streaming idle watchdogs 和 No response from API 里列了一堆计时器,但每个计时器的生效条件都不一样,读者很难对号入座。所以这次直接把几种「卡住」做出来,量它到底等多久、界面显示什么。

问题分析

从网络上看,「卡住」只有四种可能,分别对应文档里不同的计时器:

卡在哪 后端在干什么 文档里管它的计时器
① 没回响应头 连接收了,但一直不回 HTTP 头(比如上游排队、缓冲型中转在等生成完) 首字节超时(文档说:设了 ANTHROPIC_BASE_URL 时不生效),否则就是 API_TIMEOUT_MS(文档写默认 10 分钟)
② 回了头,之后静默 回了 200 和 SSE 头,然后一个字节都不发 字节级看门狗(网关默认 300 秒)、事件级看门狗(300 秒)
③ 只发 keep-alive ping 一直发 event: ping,但没有正文 ping 能重置字节级看门狗,事件级看门狗不认
④ 断在半路 正文发了一部分,然后不动了 字节级看门狗

几个和本文结论直接相关的官方原文:

  • API_TIMEOUT_MS:Timeout for API requests in milliseconds (default: 600000, or 10 minutes)(环境变量文档)
  • 首字节超时运行在直连 Anthropic API 上,but not when ANTHROPIC_BASE_URL … routes them through a gateway(network-config)
  • 自动重试:Claude Code retries transient failures up to 10 times with exponential backoff(errors)

技术方案与选型

方案 结论 理由
本地 stub 模拟四种卡法 ✅ 采用 能精确制造「不回头 / 静默 / 只发 ping / 半路断」,每个请求带毫秒时间戳记录,配合 Claude Code 的 --debug-file 能直接看到是哪个计时器触发的
拔网线、真实中转站 ❌ 排除 卡法不可控,也区分不出是哪一种;会消耗真实额度
只读文档推算 ❌ 不能单独用 实测有一处和文档不一致(见下文的 6 分钟)

隔离做法和 429 那篇 相同:env -i 清空环境、每次全新的空 CLAUDE_CONFIG_DIR、假 key、ANTHROPIC_BASE_URL 指向 127.0.0.1 上的 stub,HTTPS_PROXY 也指向 stub 以拦截一切外连。debug 日志里能看到遥测上报(1P event logging)、bootstrap、MCP registry 的外连全部被拒,没有请求到达真实服务。

-p 模式统一用 claude -p 'reply with exactly OK' --model haiku < /dev/null;交互模式在 tmux 里启动真实 TUI,每 10 秒截一帧,录了 25 分钟。

实测过程

1. 后端不回:每次等 6 分钟,不是 10 分钟

stub 收下请求,永远不回响应头。为了只看「一次请求等多久」,设 CLAUDE_CODE_MAX_RETRIES=0:

设置 结果 墙钟
API_TIMEOUT_MS 不设 Request timed out,exit 1 360.49 s
API_TIMEOUT_MS=600000 同上 360.50 s
API_TIMEOUT_MS=900000 同上 360.49 s
回了头之后静默(②),API_TIMEOUT_MS=900000 同上 360.49 s
API_TIMEOUT_MS=20000 同上 20.6 s(每次请求)

不设置时实测是 6 分钟,不是文档写的 10 分钟。把它调大到 60 万、90 万毫秒也还是 6 分钟,调小才有效。

为了确认这个 360 秒不是实验装置造成的,又做了几组对照,结果全部还是 360 秒:

对照 目的 墙钟
CLAUDE_STREAM_FIRST_BYTE_TIMEOUT_MS=60000 看首字节超时有没有在起作用 360.50 s(无效,和文档「设了 base URL 时不生效」一致)
CLAUDE_ENABLE_BYTE_WATCHDOG=0 关掉字节级看门狗 360.50 s
--tools "",请求体从 183KB 降到 91KB 看是不是按请求体大小算的 360.48 s
关掉 stub(Node)自身的 requestTimeout 等全部服务器超时 排除「其实是 stub 先断了连接」 360.44 s

最后一组很关键:Node 的 HTTP 服务器默认 requestTimeout 是 300 秒、巡检间隔 30 秒,和 360 太像了。关掉之后仍是 360 秒,而且 Claude Code 自己的日志写的是 API api_timeout after retries: Request timed out,所以这是 Claude Code 这边的行为。我在 2.1.285 的二进制里看到 SDK 客户端的超时确实写的是 API_TIMEOUT_MS 默认 600000,360 秒这个上限从哪来,没有在代码里定位到,本文只报告实测值。

2. 默认重试 10 次:可能卡一个多小时

不设任何变量、后端一直不回,这是读者「一直卡住」时最典型的情况。请求时间线(秒):

0, 361, 722, 1085, 1450, 1819, …

每 6 分钟重发一次,后几次间隔略有拉长,最长到 399 秒(疑似指数退避叠加在 6 分钟上,未在代码中确认)。完整时间线:

0, 361, 722, 1085, 1450, 1819, 2198, 2592, 2991, 3389, 3787

第 11 个请求再等满 360 秒后,在 4147.78 秒(约 69 分钟) 报 Request timed out,exit 1,stub 共收到 11 个请求。debug 日志最后一行是 API api_timeout after retries: Request timed out.。后端一直不回时,默认配置下 Claude Code 要卡 69 分钟才认输。

作为对照,API_TIMEOUT_MS=20000 时两次运行都是 11 个请求(1 次 + 重试 10 次),分别在 406.74 秒和 407.87 秒报 Request timed out。重试次数和 429 篇 测到的一样是 10 次,只是这里每次都要先等满超时。

3. 交互模式下你看到的是什么

在 tmux 里开真实会话,后端一直不回,每 10 秒截一帧,共 25 分钟。状态行的变化:

时间 界面
0 ~ 6 分钟 ✢ Clauding… (4m 34s),只有计时在涨(另一个会话里动词是 Deliberating…,动词是随机的)
6 ~ 12 分钟 ✻ API error · Retrying in 0s · attempt 1/10,倒计时停在 0s 不动
12 ~ 18 分钟 ✻ API error · Retrying in 0s · attempt 2/10
18 ~ 24 分钟 ✻ Request timed out. · Retrying in 0s · attempt 3/10
24 分钟起 ✻ Request timed out. · Retrying in 0s · attempt 4/10

「Retrying in 0s」一停就是 6 分钟,最容易让人以为死机了。其实倒计时只覆盖两次请求之间的退避间隔(这里不到 1 秒),之后新请求发出去,又是 6 分钟的等待,界面不再提示。「回了头之后静默」(②)的界面和这完全一样。

4. 只发 ping、断在半路:各有各的节奏

卡法 断开时机 debug 日志里的原因 之后
③ 只发 ping(每 15 秒一次),默认 750 秒 第 600 秒 Streaming idle warning: no chunks received for 150s,第 750 秒 Streaming idle timeout: no chunks received for 300s, aborting stream 重发,50 分钟时已发出第 7 个请求
③ 只发 ping(每 5 秒),字节超时调到 10 秒 600 秒 同上 重发,25 分钟时已发出第 3 个请求
④ 断在半路,默认 300 秒 [byte-watchdog] firing: idle=300000ms → Streaming idle timeout (byte-level) 之后每约 5 分钟重发一次,日志记为 Request timed out,50 分钟时在第 8 次重试
④ 断在半路,字节超时调到 10 秒 10 秒 同上(10000ms) 只额外重发 1 次,再断就报 API Error: stream idle: no bytes for 10000ms 结束,共 20.3~20.7 秒

两个值得注意的点:

  • keep-alive ping 救不了:ping 能骗过字节级看门狗,但事件级看门狗只认真正的响应事件,最终还是会判定卡死,而且比完全静默还要晚(750 秒对 360 秒)。
  • 断在半路时,已经收到的那部分正文会被丢掉:-p 的 stdout 里只有最后的报错,没有半截回答。

(默认组的 4 个 case 都在 50 分钟时被实验看门狗截断,表中「之后」一列是截断时的进度,不是最终结果。)

5. 缓冲型中转站:超过 6 分钟的回复永远拿不到

有些中转站不做流式转发,而是等上游把整段回复生成完,再一次性返回。对 Claude Code 来说,这就是「① 没回响应头」,一直持续到生成结束。用 stub 模拟「等 N 秒后返回正常结果」,CLAUDE_CODE_MAX_RETRIES=1:

缓冲时长 结果 stub 请求数 墙钟
300 秒 ✅ 等到了,输出 OK,exit 0 1 300.33 s
400 秒 ❌ 第 361 秒被掐断重发,重发的又在第 361 秒被掐断,Request timed out 2 721.29 s

**只要单条回复的生成时间超过 6 分钟,每一次都会在第 6 分钟被掐断重发,重试多少次都没用。**短问题正常、长任务必卡,就是这个特征。

实践效果

**1. 先确认后端通不通。**用你给 Claude Code 配的地址和 key 直接打一次流式请求,看多久出第一个字节(模型名换成你的后端支持的):

curl -sN -w '\n首字节 %{time_starttransfer}s,总计 %{time_total}s\n' \
  "$ANTHROPIC_BASE_URL/v1/messages" \
  -H "x-api-key: $ANTHROPIC_API_KEY" -H "anthropic-version: 2023-06-01" \
  -H "content-type: application/json" \
  -d '{"model":"claude-haiku-4-5","max_tokens":16,"stream":true,"messages":[{"role":"user","content":"hi"}]}'

这条命令会消耗一次很小的请求额度。正常情况下应该几秒内就开始逐行输出 event:。如果长时间没有任何输出,问题在后端或网络,不在 Claude Code。如果最后才一次性吐出全部内容,说明你的中转站在做缓冲(第 5 节的情况)。

**2. 卡住时按 Esc。**中断之后原消息还在,直接再发一次就行。不中断的话,最坏要等约 69 分钟(4147.78 秒)。

3. 想让它早点失败,而不是卡一个多小时:

export API_TIMEOUT_MS=60000          # 单次请求最多等 60 秒(只能调小,调大超过 6 分钟无效)
export CLAUDE_CODE_MAX_RETRIES=2     # 最多重试 2 次

注意:API_TIMEOUT_MS 设得太小,正常的长回复也会被掐断。它限制的是「整个请求」,不只是首字节。60 秒适合排查,日常使用要按你最长的任务来定。

**4. 用的是缓冲型中转站:**换一个支持流式转发的;或者把任务拆小,让单条回复在 6 分钟内生成完。调大 API_TIMEOUT_MS 解决不了,第 1 节已经证明调大无效。

**5. 不是转圈,而是卡在一条命令上:**那是 Bash 工具在等命令结束(默认 2 分钟超时),和本文的网络等待无关,见 Command timed out after 2m 0s。

本轮全部请求都打在本地 stub 上,真实 API 花费为 0。

踩坑

  • **差点把实验装置的超时当成结论。**360 秒和 Node 默认的 requestTimeout(300 秒)加巡检间隔太接近了。在关掉 stub 自身全部超时、确认仍是 360 秒之前,这个数不能写。
  • **心算把 6 分钟算成了 10 分钟。**看 debug 日志时把 15:04:43 → 15:10:43 当成了 10 分钟,一度以为和文档一致。时间差一律用脚本算。
  • **hang 的「连接关闭」时间戳是错的。**最初用 req.on('close') 记录连接关闭,Node 在请求体读完时就会触发它,所以全是 0 秒。最终以请求到达的时间戳和 Claude Code 自己的 debug 日志为准。

未验证清单:直连 Anthropic API(不设 ANTHROPIC_BASE_URL)时的超时,按文档首字节超时会生效(180 秒),本文没测;OAuth 订阅登录下的行为;HTTPS 的真实中转站(本文的 stub 是本机 http);360 秒上限的代码来源;只发 ping 的情况在 1500 秒后重发间隔从 750 秒变成约 300 秒的原因;断在半路时,字节超时 10 秒和默认 300 秒的重试次数为什么不同(日志里两者的错误类型不同,一个是 stream_idle_timeout,一个是 Request timed out,但没有在代码里确认)。

相关阅读

这类实测,每周六汇总一封

订阅码农早餐:每天 8:00 一封 AI 编程早报,每周六另附本周 Claude Code / Codex / 本地模型的实测和踩坑汇总。

相关文章

Claude Code 上下文太长怎么办:Prompt is too long 会自动压缩,中转站 / DeepSeek 的 maximum context length 却不会(实测)

Claude Code 靠报错文案判断「上下文太长」:后端说 prompt is too long 或 input is too long for requested model,它会自动压缩对话后重发,用户无感;DeepSeek 和 OpenAI 风格中转返回的 This model's maximum context length is …,它不认识,直接报 API Error: 400,每轮都失败。手动 /compact 有效;更好的办法是用 CLAUDE_CODE_MAX_CONTEXT_TOKENS(非 claude- 模型 ID)或 CLAUDE_CODE_AUTO_COMPACT_WINDOW(claude- 模型 ID)告诉它真实上限,让它提前压缩。Claude Code 2.1.285 + 本地 stub 实测。

claude-codedeepseek+6
pitfalls2026年10月5日8 min
3

Claude Code 429 怎么办:Request rejected (429) 原文、会重试多久、retry-after 超过 60 秒直接放弃(实测)

Claude Code 遇到 429 会先自动重试,最多 10 次、约 3 分钟。retry-after 不超过 60 秒时会等满再试(实测 10 秒、60 秒都恢复成功),61 秒及以上一次都不重试,立刻报 API Error: Request rejected (429)。中转站(new-api)的中文限流提示会原样显示,空 body 显示 status code (no body)。交互模式下每句话会同时发 2 个请求,限流额度消耗也是 2 倍。全部在本地 stub 上实测,Claude Code 2.1.285。

claude-code中转站+5
pitfalls2026年10月4日9 min
8
Claude Code MCP 显示 Connected 却 0 个工具:Invalid result for tools/list(ttlMs / cacheScope)实测与修法

Claude Code MCP 显示 Connected 却 0 个工具:Invalid result for tools/list(ttlMs / cacheScope)实测与修法

MCP server 显示已连接、工具数却是 0,日志里是 Invalid result for tools/list,ttlMs 与 cacheScope 校验失败。用自写 stub 在 Claude Code 2.1.280 / 2.1.285 / 2.1.288 上复现:根因不是「多了未知字段被严格校验拒掉」,而是 server 协商到 MCP 2026-07-28 后漏了这一版的必填字段(resultType、ttlMs、cacheScope),多加未知字段反而能正常通过。stdio 是否走新协议由一个默认关闭的远程开关决定,所以同一个版本有人中招、有人没事;2.1.280 打开协商后同样失败。用户侧设 MCP_PROTOCOL_NEGOTIATION=legacy(settings.json 的 env 也行)立即恢复,server 侧补上三个字段即可。

mcpclaude-code+4
pitfalls2026年10月3日7 min
20
Claude Code 安装失败实测:npm EACCES、镜像卡 600 秒、Node 20 静默装旧版、install.sh 返回地区拦截页、原生安装器顺手卸掉 npm 版——15 条报错原文与解法

Claude Code 安装失败实测:npm EACCES、镜像卡 600 秒、Node 20 静默装旧版、install.sh 返回地区拦截页、原生安装器顺手卸掉 npm 版——15 条报错原文与解法

在 macOS 上把 claude code 安装的失败面逐个真实复现,共 15 条报错原文,全部带墙钟和 exit code。npm 全局装到 /usr/local:EACCES,exit 243。cache 目录只是 0555,npm 却报 root-owned 并建议 sudo chown。本机 npmmirror 两次分别用了 147 秒、超过 600 秒,官方源两次都在 11–12 秒(仅 2 个样本)。Node 20 不钉版本号会静默装到 2.1.197,没有任何警告。境内直连 claude.ai/install.sh 时 curl exit 0,拿到的却是一张 447KB 的地区拦截页 HTML。原生安装器会调用 npm uninstall -g,把已有的 npm 版删掉,终端里不提示——本次实测真的删掉了本机的全局安装。

claude-codenodejs+6
pitfalls2026年9月29日11 min
134