大模型 API 錯誤碼速查:400 到 529 各代表什麼、哪些該重試
大模型 API 錯誤碼可以先按一條線分開:4xx 基本是請求本身的問題,原樣重試沒有用,要改請求、換金鑰或者等額度;5xx 和 524、529 多半是服務商或中間鏈路的問題,可以帶退避重試。例外是 429:它是 4xx,但通常值得等一會兒再試,前提是先分清“速率超了”還是“餘額沒了”。
下面先給總表,再講每一類該怎麼確認,最後給一段重試邏輯的示例。各廠商對同一個狀態碼的細分不完全一樣,表裡寫的是常見含義,具體以各家官方錯誤碼文件為準。
一張表:每個狀態碼是誰的問題、能不能重試
| 狀態碼 | 常見含義 | 通常是誰的問題 | 能否重試 | 建議等待 |
|---|---|---|---|---|
| 400 | 請求格式或引數不對,例如 JSON 結構錯、引數超出範圍、上下文超長 | 客戶端 | 否,先改請求 | — |
| 401 | 金鑰無效、缺失、已吊銷,或請求頭寫錯 | 客戶端 | 否 | — |
| 402 | 餘額不足(DeepSeek 等文件裡單列;部分廠商用 400 或 429 表達) | 賬戶 | 否,先充值 | — |
| 403 | 沒有許可權:金鑰無權訪問該資源,或所在地區不在服務範圍內 | 賬戶 / 地區政策 | 否 | — |
| 404 | 介面路徑或模型名寫錯,或該賬戶看不到這個模型 | 客戶端 | 否 | — |
| 413 | 請求體太大 | 客戶端 | 否,拆小 | — |
| 422 | 引數語義不合法(DeepSeek 等文件單列) | 客戶端 | 否 | — |
| 429 | 速率或併發超限;也可能是額度用完 | 客戶端用量 / 賬戶 | 速率類可以,額度類不行 | 優先按 retry-after 頭 |
| 500 | 服務端內部錯誤 | 服務商 | 可以 | 例如從 1 秒起指數退避 |
| 502 | 閘道器拿到了上游的無效響應 | 中間鏈路或服務商 | 可以 | 同上 |
| 503 | 服務暫不可用或過載 | 服務商 | 可以 | 同上,持續出現就降級 |
| 504 | 閘道器等上游超時 | 中間鏈路或服務商 | 可以,但先檢查請求是否太長 | 同上 |
| 524 | Cloudflare 已連上源站,但源站在規定時間內沒返回 | 源站處理太慢 | 可以,長任務建議改流式 | 同上 |
| 529 | Anthropic 的 overloaded_error,服務整體過載 | 服務商 | 可以 | 退避時間放長一些 |
兩個容易誤判的點:
- 524 和 529 不是一回事。524 是 Cloudflare 的狀態碼,只說明“經過 Cloudflare 的那段鏈路等源站等超時了”,源站可能是官方 API,也可能是你自己或中轉服務的伺服器。529 是 Anthropic 文件裡定義的過載碼,出現時說明請求已經到了 Anthropic,是對方容量不足。
- 429 有兩種。OpenAI 的 429 響應裡,
rate_limit_exceeded是速率超限,等一下就好;insufficient_quota是額度或賬單問題,重試多少次都一樣。Anthropic 的 429 是rate_limit_error,響應頭裡帶retry-after。
看到報錯,先看哪三樣東西?
狀態碼只是第一層資訊。能定位問題的是下面三樣,建議在日誌裡把它們和狀態碼一起記下來。
1. 響應體裡的錯誤型別
主流介面的錯誤響應都是 JSON,裡面有一個型別欄位:
- OpenAI 格式:
error.type、error.code、error.message - Anthropic 格式:頂層
type: "error",error.type是invalid_request_error、authentication_error、permission_error、not_found_error、rate_limit_error、api_error、overloaded_error這類值
同樣是 400,error.message 可能寫的是上下文超長,也可能是某個引數名拼錯,處理方法完全不同。只記狀態碼不記 message,事後基本沒法查。
2. request_id
OpenAI 在響應頭 x-request-id 裡返回請求 ID,Anthropic 在響應頭 request-id 裡返回(響應體裡通常也有)。找官方支援或者對比自己的服務端日誌時,靠這個 ID 才能精確對上某一次請求。
3. 響應是誰發出來的
502、504、524 這類碼經常不是模型服務商發的,而是中間某一層:公司代理、反向代理、CDN、中轉閘道器。判斷方法:
# 只看響應頭,確認是誰回的錯誤
curl -sS -D - -o /dev/null https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{}'
上面故意發一個空請求體,正常應該收到 400 加上 request-id 頭,說明網路鏈路通、請求確實到了官方。如果收到的是一個 HTML 頁面、server: cloudflare 且沒有任何請求 ID,或者是你代理軟體自己的報錯頁,那問題在鏈路上,不在模型。OpenAI 也一樣,可以對 https://api.openai.com/v1/models 發不帶金鑰的請求,預期是 401 加 x-request-id。
4xx:怎麼改請求,而不是盲目重試?
排查順序可以這樣走:
- 401:檢查環境變數是否真的被讀到(
echo ${#OPENAI_API_KEY}看長度,不要把金鑰列印出來);檢查請求頭寫法,OpenAI 格式用Authorization: Bearer,Anthropic 格式用x-api-key。用中轉或自定義介面地址時,介面地址和金鑰要配套,詳細配置見Claude Code 自定義 API 與 Codex、OpenCode 介面地址配置。 - 404:多數是 base URL 少了或多了
/v1,或者模型名拼寫不對。 - 400 / 413 / 422:讀
error.message。上下文超長就截斷歷史或換上下文更長的模型;引數問題對照文件逐個檢查。 - 403:可能是金鑰許可權不夠,也可能是服務所在地區政策的限制。後者請按官方說明處理,遵守服務條款和當地法規,參見Claude 提示所在地區不受支援:原因、官方政策與合規選擇。
- 429:先區分型別。速率類按
retry-after等待,並在客戶端加併發上限;額度類去控制檯看餘額和用量限制。
4xx 一律不要進入自動重試迴圈。一個引數寫錯的 400 被重試 5 次,只會多 5 條一樣的錯誤日誌;OpenAI 的速率限制文件還說明,失敗的請求同樣計入每分鐘限額。
5xx、524、529:是不是全域性故障?
服務端錯誤能重試,但先要回答:只有我這樣,還是大家都這樣?這決定了你是繼續排查自己的鏈路,還是等官方恢復。
三步判斷
- 看官方狀態頁和第三方監測。開啟 cdnping 的 API 狀態頁,它從 Cloudflare 邊緣每 5 分鐘探測一次各家官方 API 入口,並每 15 分鐘同步 OpenAI、Anthropic、Moonshot、Groq 等的官方狀態頁。如果是 Claude,直接看 /status/anthropic。狀態頁上的事件等級怎麼理解,可以看怎麼看 OpenAI 狀態頁和 Claude 狀態頁。
- 看使用者側反饋。官方狀態頁通常比實際故障晚一些才更新。掛了嗎頁面綜合了官方狀態、每 5 分鐘的 API 探測和使用者一鍵報告(打不開、很慢、限流等),使用者報告突然變多往往是更早的訊號。
- 從自己這邊測一次。在線上測速裡測一下目標 API 的首次連線和往返。連線本身就失敗或者很慢,問題更可能在本地網路或代理;連線正常而請求返回 5xx,更可能在服務商。分層檢查方法見ChatGPT 掛了嗎?三步判斷是服務故障還是自己的網路問題和Claude Code 連線超時和報錯怎麼排查。
5xx 事件有多常見?
按 cdnping 從各家官方狀態頁同步的記錄,2026-09-17 以來(截至 2026-10-17):OpenAI 有 4 次 major、19 次 minor 級別的事件;Claude 有 6 次 major、1 次 minor;Moonshot 有 8 次 critical。同期 Cloudflare 狀態頁上也出現過 “Increased HTTP 502 Errors”“Increased HTTP 5xx Errors Ashburn” 這類事件,說明 502、5xx 有時來自 CDN 層,而不是模型服務商。按服務商的逐條梳理見AI 服務故障盤點:2026年9–10月。
一個月的視窗裡就有這麼多事件,客戶端需要有重試和降級,不能假設上游一直可用。
當前各 API 入口可達嗎?
cdnping 在 2026-10-17 開始採集,下面是首批探測的結果(Cloudflare 邊緣 DEN 節點,UTC 08:40–10:05,共 242 次探測,視窗很短,只能看個大概):
| API 入口 | p50 | p95 | 視窗內成功率 |
|---|---|---|---|
| api.openai.com | 96 ms | 194 ms | 100% |
| api.anthropic.com | 73 ms | 84 ms | 100% |
| generativelanguage.googleapis.com | 69 ms | 89 ms | 100% |
| api.deepseek.com | 353 ms | 414 ms | 100% |
| api.moonshot.cn | 375 ms | 1125 ms | 約 94% |
| dashscope.aliyuncs.com | 615 ms | 1152 ms | 100% |
這是從美國機房測的入口可達性,不代表你本地的體驗,也不代表模型推理是否正常;它能回答的是“入口有沒有整體不通”。探測口徑見資料方法。
重試邏輯怎麼寫?
把上面的表落到程式碼裡,大致是這樣。下面是 Python 示意,send() 和 resp 的屬性是假設的介面,按你用的 HTTP 庫或 SDK 改寫:
import random, time
RETRYABLE = {500, 502, 503, 504, 524, 529}
def should_retry(status, body):
if status in RETRYABLE:
return True
if status == 429:
err = (body or {}).get("error", {})
# 額度類 429 不重試
return "insufficient_quota" not in (err.get("code"), err.get("type"))
return False
def call_with_retry(send, max_attempts=5, base=1.0, cap=30.0):
for attempt in range(max_attempts):
resp = send()
if resp.status < 400:
return resp
body = resp.json_or_none()
if not should_retry(resp.status, body) or attempt == max_attempts - 1:
rid = resp.headers.get("request-id") or resp.headers.get("x-request-id")
raise RuntimeError(f"{resp.status} {rid} {body}")
retry_after = resp.headers.get("retry-after")
if retry_after and retry_after.isdigit():
delay = float(retry_after)
else:
delay = min(cap, base * 2 ** attempt) * random.uniform(0.5, 1.0)
if resp.status == 529:
delay *= 2 # 過載時等久一點,減少對方壓力
time.sleep(delay)
實現時還要注意:
- 加隨機抖動。多個程序同時失敗、同時按固定間隔重試,會在同一時刻再打一波請求。
- 設總時長上限。互動式場景下使用者等不了太久,重試 2–3 次失敗就該提示或切到備用模型。
- 流式請求的重試要小心。已經輸出了一半再失敗,直接重發會重複內容,需要在應用層決定是續寫還是重來。
- 504 和 524 反覆出現時,先看請求本身。非流式請求生成很長的輸出,很容易超過閘道器的等待時間,改成流式輸出往往比重試更有效。
- 日誌裡記下狀態碼、錯誤型別、request_id 和耗時。想進一步統計自己的成功率,可以參考自己測 AI API 的可用率:指標、指令碼與口徑。
用聚合閘道器時,錯誤碼怎麼歸屬?
經過閘道器或中轉服務時,你看到的狀態碼可能是閘道器自己生成的,也可能是透傳的上游錯誤。判斷方法還是看響應體和請求 ID,閘道器一般會在錯誤裡說明來源。
以 AGI Plan 為例(AGI Plan 是 cdnping 的商業合作方),它公開的可用率口徑是“成功 /(成功 + 因平臺自身原因失敗)”,只有 5xx 計為平臺失敗,4xx 視為請求方的問題;逐小時資料可以在 https://agiplan.dev/api/status/requests?month=YYYY-MM 查到,不需要登入,cdnping 的 /status/agiplan 也有映象。評估任何閘道器時,都可以問同樣的問題:它怎麼區分 4xx 和 5xx,可用率按什麼口徑算,資料能不能公開核對。更多檢查項見AI API 中轉站怎麼選:可用率、計費、資料政策 8 項檢查。
排查檢查表
遇到報錯時按順序過一遍: