Claude API 429 错误怎么解决?
简答:Claude API 返回 429 时,先看响应里有没有 retry-after:有就按服务端等待时间重试,并降低并发;如果 error.details.error_code 是 enforced_spend_limit_reached,通常是月度支出上限,停止盲目重试并检查 Billing。若状态码是 529,则按服务过载处理;同时记录 request_id 和完整响应头,确认 429 来自 Claude API 还是中间网关。
定义:Claude API 429 是 rate_limit_error,表示组织或工作区触发了请求数、输入 Token、输出 Token、加速限制、月度支出上限或工作区支出限制。
先看这张速查卡:30 秒判断 429 类型
先保存 HTTP 状态码、响应体、响应头和 request_id,再按下面三步处理。本站为第三方 AI API 接入指南站,与 Anthropic 无隶属关系;本文资料核对截至 2026 年 10 月 24 日。
| 你看到的信号 | 优先判断 | 立即操作 |
|---|---|---|
429,并带有 retry-after | RPM、ITPM、OTPM 或工作区临时限流 | 按响应头等待,降低并发,再重新排队 |
429,且 error.details.error_code 为 enforced_spend_limit_reached,没有 retry-after | 使用层级月度支出上限 | 停止自动重试,检查 Billing、使用层级和恢复时间 |
| 状态码为 529 | overloaded_error,服务暂时过载 | 使用指数退避,逐步恢复流量 |
官方错误文档将 429 定义为 rate_limit_error,可能对应速率限制、使用层级月度支出上限或 Claude Code 工作区支出限制;529 则表示 API 暂时过载。可对照Claude API errors 官方文档和Rate limits 官方文档。
先确认 429 响应是不是 Claude API 返回的
如果请求经过 API Router、兼容接口、反向代理或网关,不要看到 429 就直接套用上游规则。建议同时检查以下信号:
- 错误体是否接近官方结构:顶层有
type: error、error.type、error.message和request_id。 - 响应头是否包含
request-id、retry-after或anthropic-ratelimit-*。 request_id或request-id是否呈现req_开头的请求标识。- 网关日志中是否同时记录了上游状态码、上游响应体和自己的限流规则。
- 如果只有网关自定义的错误格式、没有上游请求标识和 Anthropic 限流头,应优先查看网关文档,而不是断言这是 Anthropic 组织限流。
官方说明,错误响应会包含顶层 error 对象和 request_id;每个响应还会有 request-id 响应头,可用于定位具体请求。相关字段可查看错误响应结构与 Request ID 说明。
{
"type": "error",
"error": {
"type": "rate_limit_error",
"message": "You have reached your API usage limits",
"details": {
"error_code": "enforced_spend_limit_reached"
}
},
"request_id": "req_example"
}上面是根据官方结构整理的示意响应,request_id 仅用于展示格式,不代表你的真实请求。真正排查时应保存原始错误体,不要只记录“429”。
如何区分 RPM、ITPM、OTPM 和支出上限
Messages API 的速率限制主要按三个维度计算:RPM 是每分钟请求数,ITPM 是每分钟输入 Token,OTPM 是每分钟输出 Token。官方说明,组织或工作区可能在较短时间窗口内执行限制,短时间突发流量也可能触发 429。
| 响应头 | 含义 | 排查动作 |
|---|---|---|
retry-after | 本次请求至少等待的秒数 | 等待结束前不要提前重试 |
anthropic-ratelimit-requests-limit / -remaining / -reset | 请求数限制、剩余量和恢复时间 | 观察是否是 RPM 或突发流量耗尽 |
anthropic-ratelimit-input-tokens-limit / -remaining / -reset | 输入 Token 限制、剩余量和恢复时间 | 检查长上下文、重复历史和工具定义 |
anthropic-ratelimit-output-tokens-limit / -remaining / -reset | 输出 Token 限制、剩余量和恢复时间 | 检查实际输出长度和并发请求数 |
anthropic-ratelimit-tokens-* | 当前最严格 Token 限制的汇总值 | 不能仅凭这一组头判断一定是输入或输出耗尽 |
anthropic-workspace-id | 请求实际计入的工作区标识 | 核对 API Key、工作区和网关路由是否一致 |
官方响应头文档明确列出了请求数、汇总 Token、输入 Token 和输出 Token 的分项响应头;其中 anthropic-ratelimit-tokens-* 展示的是当前最严格限制的值。因此,判断 ITPM 或 OTPM 时,应同时查看输入、输出分项头,而不是只看汇总值。来源:Rate limits 的 Response headers。
如果是 ITPM,优先裁剪重复上下文、历史消息、工具定义和大段文档。官方说明,许多模型的缓存读取输入 Token 不计入 ITPM,但缓存创建输入 Token 和未缓存输入仍需纳入判断;具体行为以当前模型文档和实际响应为准。
没有 retry-after 时,为什么不能一直重试
官方给出的典型情况是:达到使用层级月度支出上限后,接口仍返回 429 和 rate_limit_error,但不带 retry-after;错误详情中的 error_code 为 enforced_spend_limit_reached。这种情况下,包括 SDK 自动重试在内的重复请求,都会在访问恢复前继续失败。
- 先读取
error.details.error_code。 - 如果值为
enforced_spend_limit_reached,停止重试。 - 到 Claude Console 的 Billing 页面检查组织月度支出上限、自己设置的支出限制和恢复时间。
- 如果是使用层级上限,按官方页面查看提升层级或申请更高限制的路径。
- 如果是自己设置的组织或工作区支出限制,调整限制后再发起新的请求。
要注意两种支出限制的状态码可能不同:达到使用层级的月度支出上限通常返回 429;达到组织或工作区自行设置的支出限制,官方错误文档说明可能返回 400,错误类型为 invalid_request_error。Claude Code 工作区的限制则可能返回带 retry-after 的 429。详见官方 Spend limits 说明。
Python:尊重 retry-after、指数退避和最大重试次数
下面的示例使用原生 HTTP 请求思路,假设 send_request() 返回类似 requests.Response 的对象。标准 API Key 的请求头应按当前认证方式配置;不要把 API Key 直接写进命令行、代码仓库或日志。官方当前的 API Key 与认证说明可查看Get your Claude API key。
import email.utils
import random
import time
from datetime import datetime, timezone
MAX_RETRIES = 3
def retry_after_seconds(response):
value = response.headers.get("retry-after")
if value is None:
return None
# 官方页面说明该字段通常是等待秒数;兼容 HTTP-date,解析失败则返回 None。
try:
return max(0.0, float(value))
except ValueError:
pass
try:
retry_at = email.utils.parsedate_to_datetime(value)
if retry_at.tzinfo is None:
retry_at = retry_at.replace(tzinfo=timezone.utc)
return max(0.0, retry_at.timestamp() - time.time())
except (TypeError, ValueError, OverflowError):
return None
def call_with_retry(send_request):
for attempt in range(MAX_RETRIES + 1):
response = send_request()
if response.status_code != 429:
return response
try:
body = response.json()
except ValueError:
body = {}
error = body.get("error") or {}
details = error.get("details") or {}
error_code = details.get("error_code")
# 月度支出上限:没有 retry-after,继续重试没有意义。
if error_code == "enforced_spend_limit_reached":
return response
if attempt == MAX_RETRIES:
return response
wait_seconds = retry_after_seconds(response)
if wait_seconds is None:
# 保守兜底:可能是网关生成的 429,交给上层按来源决定是否继续。
wait_seconds = min(60.0, 2 ** attempt)
jitter = random.uniform(0.0, 0.25)
time.sleep(wait_seconds + jitter)
return response这段代码的重试边界是明确的:429 以外的状态码交给上层处理;识别到 enforced_spend_limit_reached 立即停止;有 retry-after 时优先使用服务端等待时间;没有该字段时只使用有限的指数退避兜底。对于网关生成的 429,生产环境应结合网关日志决定是否继续,而不是默认无限重试。
如果使用官方 SDK,官方错误文档说明 SDK 会对部分连接错误、限流和 5xx 错误进行指数退避,默认重试两次,并在存在时遵守 retry-after;可以通过 max_retries 配置或关闭。业务层再加一层重试时,应计算总次数,避免 SDK 和业务代码叠加造成请求风暴。
JavaScript:读取错误体并处理 429
Node.js 的 fetch 可以读取响应头和 JSON 错误体。示例同样采用有限重试:优先使用 retry-after,没有该头时使用指数退避兜底,并在支出上限场景停止。
const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
function retryAfterSeconds(response) {
const value = response.headers.get("retry-after");
if (value === null) return null;
const seconds = Number(value);
if (Number.isFinite(seconds) && seconds >= 0) return seconds;
const dateMs = Date.parse(value);
if (Number.isFinite(dateMs)) {
return Math.max(0, (dateMs - Date.now()) / 1000);
}
return null;
}
async function callWith429Retry(makeRequest, maxRetries = 3) {
for (let attempt = 0; attempt <= maxRetries; attempt++) {
const response = await makeRequest();
if (response.status !== 429) return response;
let body = {};
try {
body = await response.clone().json();
} catch (_) {
// 网关可能返回非 JSON;保留原始响应交给上层。
}
const errorCode = body?.error?.details?.error_code;
if (errorCode === "enforced_spend_limit_reached") {
return response;
}
if (attempt === maxRetries) return response;
const retryAfter = retryAfterSeconds(response);
const waitSeconds = retryAfter ?? Math.min(60, 2 ** attempt);
const jitterSeconds = Math.random() * 0.25;
await sleep((waitSeconds + jitterSeconds) * 1000);
}
}如果你的网关不透传上游响应头,retry-after 缺失并不一定代表月度支出上限;代码中的指数退避只是保守兜底。应在上层记录网关状态、上游状态、错误体和请求标识,再决定是否继续排队。
持续 429 的解决步骤:从请求到控制台逐层排查
- 记录完整证据:保存状态码、响应体、所有响应头、请求时间、模型字段、工作区标识和
request_id,不要只记录一行异常消息。 - 检查并发与突发:把直接并发调用改为队列,按组织、工作区、模型类别或用户设置并发上限。官方说明速率限制使用 Token Bucket 算法,短时突发可能触发限制。
- 降低 RPM:给任务增加排队和令牌桶,不要让失败任务立即同时重试。
- 降低 ITPM:裁剪重复历史、无关文档、工具定义和系统提示;可以评估提示缓存,但要以实际响应字段确认缓存命中。
- 检查 OTPM:查看实际生成的
output_tokens和并发请求数。官方说明 OTPM 按实际生成的输出 Token 实时评估,max_tokens本身不计入 OTPM。 - 逐步恢复流量:如果是突然增加使用量导致的加速限制,不要一次性恢复全部并发,应逐步提高并保持稳定模式。
- 检查控制台:在 Rate limits、Usage 和 Billing 页面核对组织层级、当前限制、Token 曲线和支出上限。
- 检查 SDK 重试:确认 SDK 的
max_retries和业务层重试策略,不要让两套机制同时无限重试。
如果使用 API Router 或兼容接口,必须分别记录客户端、网关和上游三层状态。只有确认 429 来自 Claude API 后,才能按 anthropic-ratelimit-* 和 error.details.error_code 解释;由网关自行生成的 429,应按网关文档和日志处理。
400、401、404、429、529 与 unsupported_parameter 怎么区分
| 状态或错误信息 | 通常含义 | 处理方式 |
|---|---|---|
400 invalid_request_error | 请求格式、参数、模型字段或自行设置的组织/工作区支出限制有问题 | 读取错误消息,修正请求或调整自己设置的限制,不要直接重试 |
401 authentication_error | Key 缺失、失效、撤销或认证头使用错误 | 检查 API Key、OAuth Bearer 用法和环境变量;认证错误不是 429 |
404 not_found_error | 端点、资源 ID 或模型 ID 不存在,或当前组织不可用 | 核对 URL 和当前可用模型列表,不要凭记忆写模型名 |
429 rate_limit_error | RPM、ITPM、OTPM、加速限制、月度支出上限或工作区限制 | 优先读取 retry-after 和 error.details.error_code |
529 overloaded_error | API 暂时过载 | 采用指数退避并逐步恢复流量 |
unsupported_parameter | 常见于某些兼容层、路由器或 SDK 对参数不支持;当前官方 Claude API 错误总览未将其列为独立标准状态码 | 查看完整错误体,确认是哪个参数、哪一层生成,再按该层文档删除或替换参数 |
官方错误列表还包含 402、403、409、413、500 和 504。409 是资源状态冲突,413 是请求过大,500 是服务内部错误,504 是处理超时;它们不能简单当作 429 处理。可查阅官方 HTTP errors 总览与Anthropic 官方 skills 仓库的错误码参考。
排查清单与免责声明
上线前逐项确认:
- 是否保存了状态码、响应体、响应头和
request_id? - 是否区分了带
retry-after的临时限流与enforced_spend_limit_reached? - 是否设置了最大重试次数、指数退避和随机抖动?
- 是否兼容了
retry-after的秒数格式,并对异常日期格式采取保守处理? - 是否确认 429 来自上游 API,而不是网关或兼容层?
- 是否检查了 SDK 的
max_retries,避免重复叠加? - 是否把 API Key 放在环境变量或密钥管理器中,并避免写入日志、命令行历史和错误上报?
官方限额、错误字段、模型可用性、控制台入口和 SDK 行为可能调整。本文不承诺具体额度或恢复时间;模型 ID、组织层级、工作区设置和网关行为应以当前官方文档、控制台和服务商文档为准。
常见问题
Claude API 429 一般要等多久?
如果响应带有 retry-after,应按该响应头给出的等待秒数处理,不要用固定的几秒替代服务端值。如果没有 retry-after,且错误详情包含 enforced_spend_limit_reached,就不能按普通短暂限流估计等待时间,应检查月度支出上限、使用层级和恢复时间。
Claude API 429 没有 retry-after 是什么原因?
官方文档说明,达到使用层级月度支出上限的 429 不带 retry-after,并会在访问恢复前持续失败。若错误体不是官方结构,或响应来自 API Router、网关和兼容接口,也可能是中间层自行生成的 429,应结合网关日志确认来源。
降低 max_tokens 能解决 Claude API 429 吗?
不一定。官方说明 OTPM 按实际生成的输出 Token 实时评估,max_tokens 本身不计入 OTPM;更直接的做法通常是降低并发、减少实际输出长度、排队,以及在 ITPM 场景下缩短重复输入上下文。
429 和 529 有什么区别?
429 是 rate_limit_error,重点检查请求数、输入 Token、输出 Token、加速限制和支出限制;529 是 overloaded_error,表示 API 暂时过载。两者都可能使用退避,但 429 需要先读取 retry-after 和 error.details.error_code。
官方 SDK 已经会重试,还需要自己写重试吗?
不一定。官方错误文档说明 SDK 会对部分连接错误、限流和 5xx 错误进行指数退避,默认重试两次,并在存在时遵守 retry-after。若增加业务层重试,应设置总次数上限,并阻止 enforced_spend_limit_reached 场景继续重试。
参考资料
- Claude Platform Docs:Claude API errors(platform.claude.com)
- Claude Platform Docs:Rate limits(platform.claude.com)
- Anthropic 官方 skills 仓库:HTTP Error Codes Reference