Codex 报「exceeded retry limit, last status: 429 Too Many Requests」:原因与 解决
Codex 打印「exceeded retry limit, last status: 429 Too Many Requests」,表示 model provider 返回了 HTTP 429,而 Codex 已经停止重试。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),只有响应带 Retry-After 头时 Codex 才会重试 429,在 Router One 这类自定义 provider 上最多重试 stream_max_retries 次(默认 5 次);报错末尾的 request id 取自响应头,优先读 x-request-id。这句报错是 Codex 自己的,下一步要看 429 是谁返回的。把 Router One 配成 provider 时,先看控制台 → 日志:日志里有记录的 429,是网关重试之后上游仍返回的;没有记录、且按同一频率反复出现,指向网关对你的 Key 或账户的限额,这类限额可以发邮件到 support@router.one 申请调高。网关在中国大陆可直连,不需要 VPN。
这条 报错是 什么 意思
这行报错里的状态码和 request id 都来自 Codex 收到的最后一个 HTTP 响应。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),exceeded retry limit 是 Codex「重试上限」这个错误的固定文字;last status 后面是那个响应的 HTTP 状态,打印成 429 Too Many Requests;响应带 x-request-id 头时,后面再接 , request id: …,没有这个头就依次改读 x-oai-request-id、cf-ray。在 Codex 的终端界面里,这一行显示为红色,开头是 ■。别被字面意思误导:Codex 不一定真的重试过,不带 Retry-After 的 429 在第一次响应时就会得到同一句话。凡是不属于下表前四类(用量上限、套餐不含 Codex、配额、flex)的 429,Codex 都用这句话报告;看到它时,Codex 已经不会再重试了。
Codex 怎样 重试 429
按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),Codex 有两层重试,429 只会走到第二层:
- HTTP 层最多重试 request_max_retries 次(默认 4 次),只管 5xx 响应和网络传输错误;它的重试策略不含 429,所以 429 直接交给采样循环。
- 采样循环(sampling loop,Codex 包在每次模型请求外面的那层循环)只在响应带 Retry-After 头(秒数或 HTTP 日期)时重试 429:Codex 等到那个时间再重发,最多 stream_max_retries 次(默认 5 次),等待期间显示 Reconnecting... 1/5、2/5 等进度。
- 内置的 OpenAI provider 走 WebSocket 传输:Codex 不显示第一行 Reconnecting...,这些重试用完后会回退到 HTTPS 并重新计数,同一个 429 的重试次数因此大约翻倍。自定义 provider 不设 supports_websockets 就不走 WebSocket,所以对下面的 Router One 配置来说,stream_max_retries 就是全部的重试次数。
- 不带 Retry-After 的 429 会立刻结束这一轮:不会出现 Reconnecting... 行,直接打印这句报错。
- 这两项都按自定义 provider 设置,写在 [model_providers.<id>] 下,取值上限都是 100,写得更大也按 100 算。调大 stream_max_retries 只会给带 Retry-After 的 429 增加重试次数。
- OpenAI 的 Codex 配置参考(2026-10-17 核对)写的默认值相同:request_max_retries 为 4,stream_max_retries 为 5。
哪些 429 会变成这句 报错
Codex 先读 429 响应 JSON 里的 error 对象,再决定打印哪句话。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对):
| 429 响应里的内容 | Codex 打印的内容 | Codex 是否重试 |
|---|---|---|
| error.type 为 usage_limit_reached(ChatGPT 套餐的用量上限) | 以 You’ve hit your usage limit 开头的提示,或以其他说法写明用量上限、工作区额度或消费上限的提示 | 不重试 |
| error.type 为 usage_not_included | 以 To use Codex with your ChatGPT plan, upgrade to Plus 开头的提示 | 不重试 |
| error.type 为 insufficient_quota,或 error.code 为 insufficient_quota、credit_balance_exhausted、organization_spend_limit_exceeded、project_spend_limit_exceeded、organization_usage_limit_exceeded 之一 | Quota exceeded. Check your plan and billing details. | 不重试 |
| error.code 为 flex_unavailable | Flex capacity unavailable. | 不重试 |
| 其他 429 | exceeded retry limit, last status: 429 Too Many Requests,有 request id 头时后面再接 , request id: … | 只在带 Retry-After 时重试,最多 stream_max_retries 次 |
经 Router One 时:这个 429 是谁的
不管 429 是谁返回的,Codex 都打印同一句话,所以先按报错时间看控制台 → 日志。日志里有记录的 429,是网关重试之后上游仍返回的。网关对这把 Key、这个账户或账户在单个模型上的限额会在调用任何模型之前拒绝请求:这类 429 在控制台 → 日志里没有记录,只要流量不变,就按同一频率反复出现。流式请求在输出任何内容之前就遇到上游限流时也可能没有记录,所以没有记录、但突发出现又会自行消散的 429,同样指向上游。接下来:
- 日志里有记录:模型上游的限额在网关重试之后仍未解除。稍后重发,同一个模型上少开几个并行的 Codex 会话,或者把 model 行换成 /models 里列出、且模型页列有 POST /v1/responses 的其他模型。
- 没有记录、每次频率都一样:是网关对 Key 或账户的限额。把任务错开,把流量大的任务分到单独的一把 Key 上,或者申请调高限额(见下一节)。
- 没有记录、突发出现又自行消散:按上游限流处理,稍后重发。
- 留好 Codex 打印的 request id,写邮件给 support@router.one 时附上。
申请 调高 网关 限额
Router One 对每把 Key 和每个账户的请求数与 token 数限额是平台默认值,不能在控制台里自己改:需要更高吞吐时,发邮件到 support@router.one,写明账户 ID、Key 以及预计峰值的每分钟请求数与 token 数,申请调高;网关限额之上仍受上游容量约束。再开一把 Key,可以让流量大的任务不再挤占原来那把 Key 的限额,但同一账户的 Key 仍共享账户级限额。
用一键 命令把 Codex 接到 Router One
带上你的 Router One Key 运行一键命令。它会在缺少 Codex CLI 时先安装,备份已有的 config.toml,写入下一节那份配置(provider 为 router,env_key = ROUTER_ONE_API_KEY),把 Key 写进 shell 配置文件,再发一个测试请求验证连通。Windows 用 PowerShell 那一行。
curl -fsSL https://router.one/install/codex.sh | bash -s -- sk-your-api-key # Windows PowerShell: $env:ROUTER_ONE_API_KEY = "sk-your-api-key"; irm https://router.one/install/codex.ps1 | iex
一键命令 写入的 config.toml
request_max_retries 和 stream_max_retries 如果要改,也写在 [model_providers.router] 这个块里;一键配置不设置这两项,保持 Codex 的默认值。顶层的 model = "gpt-5.6-sol" 和 model_provider = "router" 两行写在第一个表头之前,块里保留 wire_api = "responses" 和 env_key = "ROUTER_ONE_API_KEY"。下面就是一键安装写入的完整文件:
model = "gpt-5.6-sol" model_provider = "router" model_reasoning_effort = "high" model_verbosity = "high" web_search = "live" [model_providers.router] base_url = "https://api.router.one/v1" env_key = "ROUTER_ONE_API_KEY" env_key_instructions = "Create an API key at https://router.one/dashboard/api-keys and set the ROUTER_ONE_API_KEY environment variable." name = "Router One" wire_api = "responses"
另一种 报错:ChatGPT 登录的 用量 上限
用 ChatGPT 登录时,Codex 报告套餐上限用的是另外几种提示。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),用量上限打印的是以 You’ve hit your usage limit 开头的提示,或者以其他说法写明用量上限、工作区额度或消费上限的提示,Codex 不会重试;ChatGPT 登录用不了的模型会收到另一种回复,见「model is not supported」报错页(https://router.one/zh/codex-model-not-supported)。把 Router One 配成 model provider 的 Codex 会话,请求用你的 Router One Key 发往 https://api.router.one/v1,不经过 ChatGPT 登录;完整配置见 Codex CLI 国内接入(https://router.one/zh/codex-china)。
常见 问题
「exceeded retry limit」是 Router One 的报错吗?
不是。这是 Codex 自己对停止重试的 429 给出的提示,不管 429 来自哪台服务器。把 Router One 配成 provider 时,看控制台 → 日志就能分清是谁的 429:日志里有记录的 429,是网关重试之后上游仍返回的。
Codex 为什么 没有 重试 这个 429?
因为响应没带 Retry-After 头。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),Codex 只在采样循环里、且 Retry-After 告诉它要等多久时才重试 429;HTTP 层的重试(request_max_retries)从不覆盖 429。等限额重置后再发一次,并到控制台 → 日志看看是谁的限额。
把 stream_max_retries 或 request_max_retries 调大能 解决吗?
多半不能。stream_max_retries 只给带 Retry-After 的 429 增加重试次数,request_max_retries 根本不管 429,而且两项的取值上限都是 100(按 openai/codex 源码,rust-v0.163.0,2026-10-17 核对)。重试再多也不会抬高限额本身:降低负载,或者申请调高 Key 或账户的网关限额。
报错 里写的是 401 Unauthorized 或 503 Service Unavailable,不是 429,处理 方法 一样吗?
不一样。按 openai/codex 源码(rust-v0.163.0,2026-10-17 核对),这句报错在 Codex 处理 429 的分支里生成,「last status」后面不会是 401 或 503。503 会换一种说法报告:带 server_is_overloaded 错误码时是「Selected model is at capacity. Please try a different model.」(见 https://router.one/zh/codex-model-at-capacity);带 slow_down 错误码时是「rate limit exceeded」加服务端的说明;其他 503 打印以「unexpected status 503 Service Unavailable」开头的提示。较早的版本(例如 rust-v0.46.0)会把重试过的 401 或 503 也报成「exceeded retry limit」,所以先升级 Codex,再看新的报错。经 Router One 时,401 表示网关拒绝了 Codex 发出的 Key:检查启动 Codex 的 shell 里 ROUTER_ONE_API_KEY 是不是你当前的 Key,以及这把 Key 在控制台 → API 密钥里是否仍然有效。如果这个变量没有设置或为空,Codex 不会发出请求,而是打印以「Missing environment variable」开头的提示。
再开一把 API Key 能绕过 限额吗?
只能绕过单把 Key 的那一部分。再开一把 Key,可以让流量大的任务不再挤占原来那把 Key 的限额,但同一账户的 Key 仍共享账户级限额;如果撞上的是账户级限额,就申请调高。
怎样 申请 更高的 限额?
发邮件到 support@router.one,写明账户 ID、Key 以及预计峰值的每分钟请求数与 token 数。Router One 对 Key 和账户的限额是平台默认值,不在控制台里设置;网关限额之上仍受上游容量约束。
在中国 大陆能用这套 配置吗?
能。网关在中国大陆可直连、无需 VPN,配置和在其他地区完全一样:同一份 config.toml,同一个 ROUTER_ONE_API_KEY 变量。遇到 429 也一样,先看控制台 → 日志。