ClaudeCN

Claude API 429 错误怎么解决?

更新于 2026-10-24 · claudecn.cyou

简答: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-afterRPM、ITPM、OTPM 或工作区临时限流按响应头等待,降低并发,再重新排队
429,且 error.details.error_code 为 enforced_spend_limit_reached,没有 retry-after使用层级月度支出上限停止自动重试,检查 Billing、使用层级和恢复时间
状态码为 529overloaded_error,服务暂时过载使用指数退避,逐步恢复流量

官方错误文档将 429 定义为 rate_limit_error,可能对应速率限制、使用层级月度支出上限或 Claude Code 工作区支出限制;529 则表示 API 暂时过载。可对照Claude API errors 官方文档和Rate limits 官方文档。

先确认 429 响应是不是 Claude API 返回的

如果请求经过 API Router、兼容接口、反向代理或网关,不要看到 429 就直接套用上游规则。建议同时检查以下信号:

  1. 错误体是否接近官方结构:顶层有 type: error、error.type、error.message 和 request_id。
  2. 响应头是否包含 request-id、retry-after 或 anthropic-ratelimit-*。
  3. request_id 或 request-id 是否呈现 req_ 开头的请求标识。
  4. 网关日志中是否同时记录了上游状态码、上游响应体和自己的限流规则。
  5. 如果只有网关自定义的错误格式、没有上游请求标识和 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 自动重试在内的重复请求,都会在访问恢复前继续失败。

  1. 先读取 error.details.error_code。
  2. 如果值为 enforced_spend_limit_reached,停止重试。
  3. 到 Claude Console 的 Billing 页面检查组织月度支出上限、自己设置的支出限制和恢复时间。
  4. 如果是使用层级上限,按官方页面查看提升层级或申请更高限制的路径。
  5. 如果是自己设置的组织或工作区支出限制,调整限制后再发起新的请求。

要注意两种支出限制的状态码可能不同:达到使用层级的月度支出上限通常返回 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 的解决步骤:从请求到控制台逐层排查

  1. 记录完整证据:保存状态码、响应体、所有响应头、请求时间、模型字段、工作区标识和 request_id,不要只记录一行异常消息。
  2. 检查并发与突发:把直接并发调用改为队列,按组织、工作区、模型类别或用户设置并发上限。官方说明速率限制使用 Token Bucket 算法,短时突发可能触发限制。
  3. 降低 RPM:给任务增加排队和令牌桶,不要让失败任务立即同时重试。
  4. 降低 ITPM:裁剪重复历史、无关文档、工具定义和系统提示;可以评估提示缓存,但要以实际响应字段确认缓存命中。
  5. 检查 OTPM:查看实际生成的 output_tokens 和并发请求数。官方说明 OTPM 按实际生成的输出 Token 实时评估,max_tokens 本身不计入 OTPM。
  6. 逐步恢复流量:如果是突然增加使用量导致的加速限制,不要一次性恢复全部并发,应逐步提高并保持稳定模式。
  7. 检查控制台:在 Rate limits、Usage 和 Billing 页面核对组织层级、当前限制、Token 曲线和支出上限。
  8. 检查 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_errorKey 缺失、失效、撤销或认证头使用错误检查 API Key、OAuth Bearer 用法和环境变量;认证错误不是 429
404 not_found_error端点、资源 ID 或模型 ID 不存在,或当前组织不可用核对 URL 和当前可用模型列表,不要凭记忆写模型名
429 rate_limit_errorRPM、ITPM、OTPM、加速限制、月度支出上限或工作区限制优先读取 retry-after 和 error.details.error_code
529 overloaded_errorAPI 暂时过载采用指数退避并逐步恢复流量
unsupported_parameter常见于某些兼容层、路由器或 SDK 对参数不支持;当前官方 Claude API 错误总览未将其列为独立标准状态码查看完整错误体,确认是哪个参数、哪一层生成,再按该层文档删除或替换参数

官方错误列表还包含 402、403、409、413、500 和 504。409 是资源状态冲突,413 是请求过大,500 是服务内部错误,504 是处理超时;它们不能简单当作 429 处理。可查阅官方 HTTP errors 总览与Anthropic 官方 skills 仓库的错误码参考。

排查清单与免责声明

上线前逐项确认:

官方限额、错误字段、模型可用性、控制台入口和 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 场景继续重试。

参考资料

  1. Claude Platform Docs:Claude API errors(platform.claude.com)
  2. Claude Platform Docs:Rate limits(platform.claude.com)
  3. Anthropic 官方 skills 仓库:HTTP Error Codes Reference