全部文章

LLM API 错误码跨服务商参考:4xx/5xx 完整对照、重试策略与边界情况

一份实用的跨服务商参考,梳理 OpenAI、Anthropic、DeepSeek 和 DashScope API 的每种 HTTP 错误码。我们对比了认证失败、限流变体、内容过滤拒绝、模型不存在响应以及流式传输中途错误,并构建了一棵决策树:何时重试、何时切换、何时直接失败。

· TheRouter

每个 LLM API 的错误返回方式都不一样。OpenAI 的 429 有四种变体。Anthropic 发明了 529。DeepSeek 有专用的 402。DashScope 把错误包在一个 code/message 信封里,有时和 HTTP 状态码矛盾。

如果你在多个服务商之间路由请求,你需要一个统一的思维模型来理解它们。我们为自己的路由层构建了这份参考,并在服务商更新错误处理方式时持续维护。

OpenAI 兼容指供应商提供一个 chat-completions 接口,其请求与响应结构与 OpenAI API 契约足够接近——只需替换三个值(API key、base URL、模型名),原来的 OpenAI SDK 调用即可直接工作。最小实践面是POST /v1/chat/completionsmessagesmodel, 并返回 OpenAI 形式的流式响应。

TL;DR — 错误码对照表

HTTP 状态码错误类型OpenAIAnthropicDeepSeekDashScope可重试?建议操作
400请求无效invalid_request_errorinvalid_request_errorInvalid Format / Invalid Parameters (422)InvalidParameter修复请求体
401认证失败invalid_authenticationauthentication_errorAuthentication FailsInvalidApiKey(HTTP 400)检查 API key
402账单/余额Insufficient Balance充值账户
403权限不足country_not_supportedpermission_error检查访问权限/地区
404未找到not_found_errorModelNotFound修复 model ID
413请求过大request_too_large缩减输入
429速率限制rate_limit_error + 3 种消费变体rate_limit_errorRate Limit ReachedThrottling / FlowControl是(限速);否(消费)退避重试;检查 Retry-After
500服务器错误server_errorapi_errorServer ErrorInternalError退避重试
503过载overloaded / slow_downServer OverloadedServiceUnavailable退避重试
529过载overloaded_error退避重试

数据检索于 2026 年 7 月 31 日。 OpenAI 来自 developers.openai.com/api/docs/guides/error-codes。Anthropic 来自 platform.claude.com/docs/en/api/errorsgithub.com/anthropics/skills。DeepSeek 来自 api-docs.deepseek.com/quick_start/error_codes。DashScope 来自 alibabacloud.com/help/en/model-studio/error-code

认证错误:401 vs 403

认证错误永远不可重试,但服务商的返回方式截然不同。

OpenAI 对四种不同原因返回 401:key 无效、key 格式错误、未加入组织、IP 白名单不匹配。他们还对不支持的国家/地区使用 403——这是地理限制,不是凭证问题。

Anthropic 清晰地区分 401(认证问题——key 错误或缺失)和 403(权限问题——key 没有访问特定模型或 beta 功能的权限)。关键细节:如果你通过 x-api-key 传递 OAuth bearer token 而不是 Authorization: Bearer,会得到 401,而非 403

DeepSeek 对所有认证失败返回 401。他们文档中没有使用 403

DashScope 对认证失败返回 400 附带 code InvalidApiKey——不是 401。这是其错误信封的一个特殊之处:HTTP 状态码是 400,但响应体内的语义错误码告诉你这是认证问题。如果你只解析 HTTP 状态码,就会把这个错误分类为"请求无效"。

实践建议

不要仅依赖 HTTP 401 来检测跨服务商的认证失败。解析错误体。DashScope 的 InvalidApiKey400 的形式到达。

速率限制错误:429 的多种变体

速率限制是最复杂的错误类别,因为服务商把 429 用于本质不同的问题。

OpenAI:四种 429

OpenAI 对四种不同原因返回 429,每种有不同的 error.code

  1. rate_limit_reached — RPM 或 TPM 超限。在 Retry-After 指定的时间后可重试。
  2. credit_balance_exhausted — 预付费额度耗尽。不可重试;需要充值。
  3. organization_spend_limit_exceeded — 组织级消费上限触发。不可重试;需要调高上限。
  4. project_spend_limit_exceeded — 项目级消费上限触发。不可重试;需要调高上限。

关键区别:只有第一种可以重试。其他三种需要账户级别的操作。如果你对消费上限 429 做指数退避重试,只会白白消耗客户端资源。

Anthropic:清晰的 429 + 独特的 529

Anthropic 仅对速率限制使用 429(RPM、ITPM、OTPM)。他们提供 retry-afterx-ratelimit-limit-*x-ratelimit-remaining-* 头。SDK 默认自动重试 4295xx 错误(指数退避,默认 2 次)。

Anthropic 的独特设计:529 overloaded_error 用于容量饱和。这与 500 api_error(服务器 bug)不同。两者都可重试,但 529 明确表示"我们很忙,稍后再试"——而非"出了故障"。

DeepSeek:429 限流,402 账单

DeepSeek 保持简洁:429 表示速率限制,402 表示余额不足。没有消费上限的 429 变体。402 是一个清晰的信号——停止重试,去充值。

DashScope:Throttling vs FlowControl

DashScope 返回 429 时有两种内部 code:Throttling(你超出了单模型的 QPM/TPM 限制)和 FlowControl(高负载时的系统级流控)。两者都可重试,但 FlowControl 可能意味着更长的等待。DashScope 还支持通过控制台临时提升限额——在流量高峰时很实用。

内容过滤与安全错误

内容过滤拒绝在所有服务商处都以 400 错误到达,但内部 code 不同:

  • OpenAI400,错误消息中包含 content_filter。流式传输时,chunk 的 finish reason 为 content_filter
  • Anthropic400 invalid_request_error,当内容违反使用政策时触发。没有独立的错误类型——与其他请求验证失败混在一起。
  • DeepSeek400 Invalid Format,消息中指出内容策略违规。
  • DashScope400 附带 code DataInspectionFailed——四家中描述最清晰的。

内容过滤错误在相同输入下永远不可重试。必须修改请求内容。

模型不存在与已下线模型错误

当你请求的模型不存在或已下线时:

  • OpenAI404,消息中列出 model ID 并建议替代方案。在模型下线日期之后,相同的 model ID 返回 404
  • Anthropic404 not_found_error。常见原因:model ID 拼写错误(如写成 claude-sonnet-4.6 而非 claude-sonnet-4-6)。别名如 claude-opus-5 可用。
  • DeepSeek:无文档记录的 404——DeepSeek 的模型空间小且稳定。
  • DashScope400 附带 code ModelNotFoundInvalidModel。模型下线日期之后的请求返回此错误。DashScope 还会在你用错误端点调用模型时(如通过图像生成端点调用文本模型)返回 InvalidModel

已下线模型的优雅降级

如果你通过多个服务商路由请求,模型不存在的错误应触发对同一或不同服务商上等效模型的切换——而非重试。参见我们的回退路由指南了解模式。

流式传输中途错误

流式传输(SSE)引入了一个微妙的问题:HTTP 连接在初始握手时返回 200,但错误可能在你已经开始处理 chunk 之后才发生。

  • OpenAI:可能在 SSE 流中发送错误事件。初始 HTTP 状态是 200,因此必须检查每个 chunk 是否包含错误事件。服务器错误期间,流也可能直接断开且没有最终的 [DONE] 标记。
  • Anthropic:成功时发送 content_block_stopmessage_stop 事件,失败时发送 error 事件类型。其流式协议是事件类型化的,错误检测比 OpenAI 的格式更清晰。
  • DeepSeek:遵循 OpenAI 兼容的 SSE 格式。中途错误以错误 chunk 出现,断连可能没有 [DONE]
  • DashScope:使用 OpenAI 兼容端点时,遵循与 OpenAI 相同的 SSE 错误模式。原生 DashScope 协议有自己的事件格式。

更多流式实现差异,参见我们的跨服务商流式传输指南

实践建议

永远不要假设 HTTP 200 意味着整个响应会成功。必须实现流级别的错误处理器。

网关错误归一化

在跨服务商路由请求时,不同的错误格式是一个实际问题:你的客户端代码需要为 N 个服务商编写 N 种不同的错误处理器。路由网关应该将上游错误归一化为统一的下游契约。

我们建议映射到以下错误分类:

下游分类映射来源可重试操作
auth_error401、403、DashScope InvalidApiKey修复凭证
invalid_request400(除内容过滤外)、413、422修复请求
content_filtered400 + 内容策略标记修改内容
rate_limited429(仅限速率变体)退避重试
billing_error402、429(消费/额度变体)充值 / 调高上限
model_unavailable404、ModelNotFound切换到替代模型
provider_error500、503、529重试后切换

在元数据字段中保留上游服务商的错误码和消息。调试生产问题的开发者需要看到原始的 credit_balance_exhausted 错误码,而不只是一个 "billing_error"。

TheRouter 路由 OpenAI 兼容请求到配置的服务商,并在实际产品路径支持时提供模型回退。错误归一化是路由契约的一部分——上游的 429 和 5xx 错误在配置后会触发回退链。

决策树:重试 vs 切换 vs 失败

收到错误
├── HTTP 状态码是 429?
│   ├── error.code 是消费/额度/账单类?
│   │   └── 失败 — 不可重试;需要账户操作
│   └── error.code 是速率限制类?
│       ├── 有 Retry-After 头?
│       │   └── 等待指定时间,然后在同一服务商重试
│       └── 没有 Retry-After
│           └── 指数退避重试(最多 3 次)
│               └── 仍然失败?→ 切换到下一个服务商
├── HTTP 状态码是 500、503 或 529?
│   └── 指数退避重试(最多 3 次)
│       └── 仍然失败?→ 切换到下一个服务商
├── HTTP 状态码是 400(内容过滤)?
│   └── 失败 — 必须修改内容;切换服务商无效
├── HTTP 状态码是 400、401、403、404、413 或 422?
│   └── 失败 — 客户端问题;修复请求
└── HTTP 状态码是 402?
    └── 失败 — 账单问题;充值账户

常见问题

哪些 LLM API 错误可以安全重试?

HTTP 429(仅限速率限制变体,非消费/额度变体)、500(服务器错误)、503(过载)和 529(Anthropic 过载)通常可以通过指数退避安全重试。除速率限制 429 外的所有 400 系列错误都需要客户端修改。参见速率限制对比了解各服务商的具体限制。

为什么 OpenAI 会返回不同类型的 429 错误?

OpenAI 使用 429 表示至少四种不同原因:RPM/TPM 速率限制、信用额度耗尽、组织消费上限和项目消费上限。检查 error.code 字段区分 rate_limit_reachedcredit_balance_exhaustedorganization_spend_limit_exceededproject_spend_limit_exceeded。只有 rate_limit_reached 可以重试。

Anthropic 的 529 错误码是什么?

Anthropic 返回 HTTP 529overloaded_error)表示 API 暂时达到容量上限。这与 500api_error,表示服务端 bug)不同。两者都可通过指数退避重试。如果 529 持续出现,考虑路由到负载较低的模型——Haiku 级别的模型通常有更多可用容量。

DeepSeek 如何区别处理余额不足和 OpenAI 不同?

DeepSeek 使用专门的 HTTP 402Insufficient Balance)状态码,而 OpenAI 将其合并在 429 中通过 credit_balance_exhausted 错误码区分。DeepSeek 的方式更清晰——402 永远不可重试,始终意味着需要充值

LLM API 在 SSE 流式传输中信号错误的方式不同吗?

是的。所有服务商都可能在初始 SSE 连接返回 HTTP 200,但随后在流中途发送错误事件。务必实现流级别的错误处理器——不要仅凭 200 就认为整个响应会成功。参见我们的流式传输实现指南了解代码模式。

路由网关应该如何归一化跨服务商的错误?

将上游错误映射为统一的下游契约:将每个错误分类为 auth_errorinvalid_requestrate_limitedcontent_filteredmodel_unavailableprovider_error。在元数据中保留上游错误码和消息以便调试。这样客户端只需编写一套重试/切换处理器,无论哪个服务商处理了请求。参见我们的网关对比了解不同路由方案如何处理这个问题。

故障期间在哪里查看服务商状态页面?

客服支持