错误码与排障
适用角色:开发者 更新日期:2026-08-06
本页列出常见错误响应,并给出对应的检查顺序、重试和超时建议。
一、错误码速查
| HTTP 码 | 错误代码 | 含义 | 你该做什么 |
|---|---|---|---|
| 400 | invalid_request_error |
请求参数非法 | 检查请求体格式、参数 |
| 401 | invalid_api_key / authentication_error |
API Key 无效或缺失 | 检查 Authorization: Bearer 头;OpenAI 兼容端点返回 invalid_api_key,Messages 兼容端点返回 authentication_error |
| 403 | insufficient_balance |
组织余额不足 | 联系所属组织充值 |
| 403 | USAGE_LIMIT_EXCEEDED |
子用户额度封顶 | 联系主用户上调额度池上限 |
| 403 | region_not_admitted |
当前账号不符合目标分组的区域或授权策略 | 改用已授权模型分组,或联系平台核对组织授权。注意:OpenAI 兼容端点和 Messages 兼容端点返回该错误码的响应体结构不同,解析时需兼容两种形态 |
| 403 | API_KEY_EXPIRED |
API Key 已过期 | 联系主用户重新分发 Key |
| 403 | fingerprint_routing_disabled |
分组标识路由未开启 | 联系主用户在组织设置中开启分组标识路由 |
| 403 | group_not_allowed |
目标分组不在可用范围 | 确认分组授权,或改用已授权分组 |
| 403 | 未绑定分组 / 默认路由配置失效 | Key 未绑定分组,或已绑定分组不匹配目标模型且默认配置失效 | 先为 Key 绑定有效分组;必要时更新默认模型配置 |
| 429 | API_KEY_RATE_{5H,1D,7D}_EXCEEDED |
Key 的限额耗尽(5h / 1d / 7d 窗口) | 等限额窗口重置或调高限额 |
| 429 | API_KEY_QUOTA_EXHAUSTED / 并发类 |
Key 额度耗尽或并发超限 | 调整 Key 额度 / 降低并发 / 联系主用户。注意:OpenAI 兼容端点返回顶层 code 字段,Messages 兼容端点返回 error.type 嵌套结构 |
| 502 | upstream_error |
模型供应商返回 5xx,统一映射 | 稍后重试 |
| 500 | internal_server_error |
平台自身故障 | 联系技术支持 |
403 和 429 的具体
code可能随触发条件不同而变化。客户端应先按 HTTP 状态码分类,再读取响应中的code,不要只依赖单个错误字符串。API_KEY_RATE_5H_EXCEEDED、API_KEY_RATE_1D_EXCEEDED和API_KEY_RATE_7D_EXCEEDED可用于识别对应限额窗口。
关于 429 细分:限额耗尽按时间窗口返回
API_KEY_RATE_5H_EXCEEDED/API_KEY_RATE_1D_EXCEEDED/API_KEY_RATE_7D_EXCEEDED,等窗口重置即可;额度耗尽 / 并发超限需调整额度或降低并发。
上游服务返回的 5xx 会映射为 502,平台自身故障返回 500。403 通常需要调整余额、权限或额度;429 通常需要等待窗口重置、降低频率或调整额度。
403 的三种分型(排障方向完全不同)
同样是 403,处置动作差别很大,先看 code 再动手:
| 分型 | 典型 code | 真因 | 正确动作 | 常见误判 |
|---|---|---|---|---|
| 区域或授权策略不匹配 | region_not_admitted |
当前账号不符合目标分组策略 | 改用已授权模型分组,或联系平台核对授权 | 反复重试同一不可用分组 |
| 分组未授权 | 未授权类 | 分组没开给这个组织 / 子用户 | 找主用户或平台开通分组授权 | 以为是没充值 |
| 余额或额度不足 | 余额/额度类 | 组织余额不足,或子用户按量额度封顶 | 充值 / 上调额度 | 以为整个账户都停了,绑了订阅分组的 Key 不受影响 |
关于第三种,有个容易踩的坑:能不能调是按每把 Key 绑定的分组单独判定的。组织余额为 0 时,订阅型 Key 照常可用,只有按量型 Key 会 403。想确认哪把 Key 现在能用,去控制台「API Key」页看「计费来源」列和顶部汇总条,以该页面展示为准。
region_not_admitted 表示当前账号不符合目标分组的区域或授权策略。客户端可向用户展示脱敏后的提示,并引导其改用已授权模型分组。更多背景见 模型可用范围与分组授权。
带分组标识的调用会固定进入对应分组。分组未授权或账号不可用时,平台返回错误,不会自动切换或降级。普通模型名要求 Key 已绑定分组;只有绑定分组不包含目标模型时,才查询默认模型配置。机制见 调用指南与路由说明。
二、错误响应体格式
平台的错误响应体有多种形态,做错误解析时需要同时兼容。
形态 A:请求校验类(error 对象嵌套结构)
400 参数错误、401 认证失败、502 模型供应商故障等由平台返回,错误信息在 error 对象里。注意:是否带最外层 type: "error" 取决于命中的是 Messages 兼容端点还是 OpenAI 兼容端点,同一端点、不同分组,外层结构会不同:
// Messages 兼容端点
{
"type": "error",
"error": { "type": "upstream_error", "message": "Upstream service temporarily unavailable" }
}
// OpenAI 兼容端点, 没有最外层 type
{
"error": { "type": "invalid_request_error", "message": "..." }
}解析建议:统一读
error.type与error.message,不要依赖最外层type字段是否存在。两种端点的error对象内字段一致。
常见 error.type 取值:
error.type |
对应场景 |
|---|---|
invalid_request_error |
400 参数错误 |
authentication_error |
401 认证失败 |
not_found_error |
404 模型或端点不存在 |
rate_limit_error |
429 限流 / 额度超限 |
permission_error |
403 权限不足 / 区域限制 |
upstream_error |
502 模型供应商故障 |
形态 B:认证 / 计费 / 限额类(顶层 code / message 结构)
最高频的 403 余额/额度、429 限额/额度等业务错误采用不同结构,错误代码在顶层 code 字段(字符串),没有外层 type/error 包裹:
{
"code": "API_KEY_RATE_5H_EXCEEDED",
"message": "rate limit exceeded"
}形态 C:500 平台内部故障
{
"code": 500,
"reason": "internal_server_error",
"message": "internal error"
}错误解析应同时兼容顶层
code和error.type。500 响应还可能包含整数code与reason;客户端应保留未知字段,避免因新增错误类型而解析失败。
三、判断"这是谁的问题"
收到错误后,按 HTTP 状态码判断方向:
- 4xx — 请求本身有问题(参数错误、认证失败、余额不足、限额超限、默认路由配置失效)。检查请求内容。如果带分组标识却报
fingerprint_routing_disabled或group_not_allowed(需启用分组标识路由),说明该分组不在可用范围或当前不可用(不会自动降级),请改用可用分组或联系平台。如果使用默认路由却报错,可能是默认路由配置的分组已失效,请联系主用户更新配置。 - 500 — 平台自身故障,请联系客服支持。
- 502 — 模型供应商侧故障(供应商返回 5xx 统一映射为 502),请稍后重试。
不确定是平台还是模型供应商故障时,先确认错误码:502 指向模型供应商,500 指向平台自身。
四、推荐的重试策略
import time
from openai import OpenAI
client = OpenAI(api_key="YOUR_API_KEY", base_url="https://<接口地址>")
def chat_with_retry(messages, max_retries=3):
for attempt in range(max_retries):
try:
return client.chat.completions.create(
model="deepseek-v4-flash",
messages=messages,
timeout=60
)
except Exception as e:
status = getattr(e, "status_code", None)
# 4xx 客户端错误不重试(重试也没用)
if status and 400 <= status < 500 and status != 429:
raise
# 429/502/500 指数退避重试
if attempt < max_retries - 1:
wait = 2 ** attempt # 1s, 2s, 4s
time.sleep(wait)
else:
raise原则:
- 4xx(除 429)不重试,参数/认证/余额/Key 过期、带分组标识分组不可用等问题,重试无意义;需按错误类型处理(检查参数、联系主用户充值或重发 Key、改用可用分组等)
- 429 / 502 / 500 才重试,用指数退避(1s→2s→4s),避免过多请求
- 设置 timeout,建议 60s,避免请求无限挂起
- 限制最大重试次数,通常 3 次,避免无限重试
五、流式(SSE)场景的特殊处理
流式请求中途出错时,你会先收到部分内容块,然后收到一个 error 事件:
data: {"choices":[{"delta":{"content":"前半段内容"}}]}
data: {"type":"error","error":{"type":"upstream_error","message":"..."}}随后连接断开。处理建议:
- 在 SSE 解析逻辑中单独识别 error 事件,不要当成正常内容
- 客户端已渲染的"半截内容"需要业务层决定如何处理(清除/标注中断/允许重新生成)
- 这是流式调用最易踩坑的场景,建议封装统一的流式错误处理
六、找技术支持时提供什么
联系平台支持时,附上以下信息可加快定位:
- 出错的时间点(精确到分钟、含时区)
- 调用的模型调用名(模型名称或带分组标识)和端点
- HTTP 状态码和完整错误响应体
- 是否流式(
stream) - 大致调用频率(帮助判断是否限流)