Troubleshooting · 过载

529 overloaded — 它有两条到达路径,只有一条会被自动重试

30 秒版
  1. 先分清它是怎么来的:HTTP 529 已经被自动退避重试过了;流里的 overloaded_error 走的是另一条路,标准重试机制管不到它——「跑一半突然断、一次没重试」就是这一种。
  2. 529 不是 429。529 是服务整体饱和,不计入你的配额,你这边没有任何杠杆——并发、缓存、档位一个都不管用。
  3. 能缩短等待的只有两件事:换一个同级模型继续干活,或在无人值守场景里让客户端一直重试下去。

同一个 529,有人看到的是重试了十次才放弃,有人看到的是一次都没重试就断在回答中间。这不是随机,也不是 bug——它是两条到达路径的差别。作为 HTTP 状态码返回的 529 走标准重试通道;而流式请求早就先返回了 200,过载只能作为流里的一个事件送达,官方文档明确写着这种情况下错误处理不走标准机制。搞清楚你手上是哪一种,比问「该等多久」有用得多。

你看到的报错

以下任意一种
API Error: 529 {"type":"error","error":{"type":"overloaded_error","message":"Overloaded"}}

API Error: Repeated 529 Overloaded errors. The API is at capacity — this is usually temporary. Try again in a moment. If it persists, check https://status.claude.com.

✻ API Error · Retrying in 8s · attempt 3/10

529 Overloaded

model overloaded · 模型过载,请稍后重试

还有一种,它不长这个样子,而且正是它最容易被误判成「网络断了」:

流式响应里的 SSE 事件(HTTP 状态码是 200)
event: error
data: {"type": "error", "error": {"type": "overloaded_error", "message": "Overloaded"}}

两条到达路径:同一个错误,不同的命运

HTTP 529 — 请求还没开始就被拒流里的 overloaded_error — 回答到一半
HTTP 状态码529200 — 响应头早就发出去了
错误类型overloaded_erroroverloaded_error完全一样
怎么送达响应体 JSONSSE 流里的一个 event: error
走标准重试吗走。官方 SDK 默认退避重试 2 次;Claude Code 默认最多 10 次不走。官方文档原话:这种情况下错误处理不遵循标准机制
你看到它时重试预算已经用完了可能一次都没重试过
典型体感转圈很久,然后报错字打到一半停住,像是断网
已经产生的输出没有已经花掉了,而且那半截回答通常留不下来
这条差别的实际后果是:在长回答、长工具链的场景里,把 529 的处理只写在「检查状态码等不等于 529」上,会静默漏掉一整类失败。流式集成需要单独处理流内的 error 事件。

529 和 429:共用「你被拒了」的体感,其余毫无共同点

529 overloaded429 rate limit
谁的问题服务整体饱和,影响所有人你的组织越过了某条线
计入你的配额吗不计入就是配额本身
retry-after不保证有普通限流有;配额耗尽没有
你手上的杠杆没有。降并发、开缓存、提档位,全都不影响它并发、缓存、档位都有效
什么时候好上游容量缓过来时限流几秒到几分钟;配额到重置时间
该做什么等,或换模型,或让它一直重试429 排查

有一个反直觉的方向值得单独点出来,因为它会把人引到完全错误的一页上去:如果你刚刚把用量陡然拉高,然后开始收到错误,那更可能是 429 而不是 529。官方文档在 529 的说明里专门补了这条提示——用量急剧上升会撞上加速度限制,回的是 429。所以「我加量了然后就过载了」这句话里,「过载」两个字多半是记错的:去看状态码,别看体感。

按这个顺序排查

1 · 先确认它到底是不是 529#

「过载」是个很容易被套用到任何一次失败上的词。先把状态码和错误类型看清楚,因为后面每一步都建立在这个判断上。

终端
# <模型 id>:从 https://api.9coding.com/v1/models 里复制一个
curl -sS -D - -o /dev/null https://api.9coding.com/v1/messages \
  -H "Authorization: Bearer $ANTHROPIC_AUTH_TOKEN" \
  -H "content-type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{"model":"<模型 id>","max_tokens":16,"messages":[{"role":"user","content":"hi"}]}' \
  | grep -iE 'http/|retry-after|request-id'

回的是 529 才是本页说的事。回 401401 排查,回 429429 排查,什么都回不了、连不上看 连接错误

2 · 别在自动重试之上再叠一层手动重试#

HTTP 529 在冒到你眼前之前,已经被退避重试过了。你再按一次回车,是在重跑一个刚刚被证伪过若干次的假设。

先分清屏幕上的两种状态:带尝试次数的倒计时(形如 Retrying in 8s · attempt 3/10)说明它正在干活,别动它;没有倒计时、直接打印出来的报错才是重试预算用完之后的终态。

具体的重试次数与提示形态在客户端版本之间改过——请按你自己正在跑的那个版本实测确认,不要从论坛帖子里抄一个数值。

3 · 如果它断在回答中间,那是另一条路径,需要另一种处理#

字打到一半停住、没有倒计时、也没有明显报错——这一类多半是流里的 overloaded_error,而不是 HTTP 529。它的特征很好认:已经输出了一部分,然后戛然而止。

在交互式使用里,这一类只能自己重发。在你自己写的集成里,它需要显式处理:只判断响应状态码的代码看不见它,因为状态码是 200。同时要注意,与之体感几乎一样、但成因完全不同的还有代理空闲超时掐断长连接——判别方法见 流式回答中途断掉:让它输出短一点,如果短回答正常、长回答必断,那是超时不是过载。

4 · 换一个同级模型,是唯一能立刻见效的动作#

529 是容量事件,而容量是按模型紧张的——同一时刻,另一个同级模型往往是通的。这是本页唯一一个不靠等待就能恢复干活的办法。

Claude Code
/model

会话不会丢,切完继续往下干即可。可选的模型 id 从 模型列表拿,或直接读 /v1/models

5 · 无人值守场景要改的是设置,不是心态#

CI 任务和长时间自主运行的会话里,跑到一半失败的代价远大于等待。Claude Code 为此提供了一个开关,按官方错误参考,它会让容量类错误一直重试下去,而不是在默认预算用完后失败:

终端
export CLAUDE_CODE_RETRY_WATCHDOG=1

它有一条必须知道的边界:对写明了消费上限或额度耗尽的 429,它仍然立刻失败——因为对那类错误无限重试,只是一种更慢的失败方式。相关的还有 CLAUDE_CODE_MAX_RETRIES(默认 10)和 API_TIMEOUT_MS。这几项的默认值、上限、以及它们之间的相互作用在版本之间都变过,请按你正在跑的版本查环境变量参考

6 · 把等待变成可观测的,而不是反复试#

529 没有 retry-after 那样可读的契约头告诉你还要多久,所以「再试一次」是一种没有信息量的动作。能查的是服务状态:先看 状态页;直连 Anthropic 时官方报错文案会直接指向它自己的状态页,走其他端点时则指向报错里写明的那个主机。

要报障就带上 request id——每一次响应都有 request-id 头,报错体里也带同一个值。9Coding 的报错响应里形如 (request id: 2026...)。这个 id 加上时间戳、模型名和完整报错文本,才能把那一次调用查出来;只说「过载了」没法排查。

什么时候这不是你的问题

下面几条同时成立,指向的就是上游容量事件,你这边再怎么调都没用:

  • 同一时间段里,指向同一个端点的其他客户端也在失败
  • 它是在你的工作负载没有任何变化的情况下开始的,
  • 你什么都没改,它自己就恢复了
  • 换一个同级模型立刻就通。

反过来,如果只有你一个客户端在失败、而且是在你刚刚改了什么之后开始的,那大概率不是 529——回到第 1 步把状态码看清楚。

相关报错

本页内容对照官方文档逐条核实,最后核实日期 2026-09-03。带版本号的行为(重试次数、环境变量默认值)随客户端版本变化,请以你正在跑的版本为准。