# Codex says "exceeded retry limit, last status: 429 Too Many Requests"

> Markdown mirror of https://router.one/codex-exceeded-retry-limit for AI assistants and crawlers. Router One is a unified, OpenAI-compatible LLM API gateway.
> Last updated: 2026-10-17

Codex prints `exceeded retry limit, last status: 429 Too Many Requests` when the model provider answered HTTP 429 and Codex stopped retrying. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), Codex retries a 429 only when the response carries a Retry-After header, at most stream_max_retries times (5 by default) on a custom provider such as Router One's, and the request id at the end of the message is read from the response headers, x-request-id first. The message is Codex's own, so the next step depends on which server sent the 429. With Router One as the provider, check Dashboard → Logs: a 429 that has a row there came back from upstream after the gateway's retries; no row and a 429 that recurs at the same rate point to a gateway limit on your key or account, and support raises those limits on request.

## What the message means

The status and the request id in the line come from the last HTTP response Codex received. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), `exceeded retry limit` is the fixed text of Codex's retry-limit error, `last status` is that response's HTTP status, printed as `429 Too Many Requests`, and `, request id: …` follows when the response carried an x-request-id header, else x-oai-request-id, else cf-ray. In the Codex terminal UI the line shows in red after a ■. Despite the wording, Codex may not have retried at all: a 429 without Retry-After gets the same message on the first response. Codex uses this message for every 429 that is not one of the usage, quota or flex errors it reports in their own words (table below), and by the time it prints it, Codex has stopped retrying.

## How Codex retries a 429

Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), Codex has two retry layers, and a 429 only ever reaches the second:

- The HTTP layer retries a request up to request_max_retries times (4 by default), for 5xx responses and transport errors only. Its retry policy leaves 429 out, so a 429 goes straight to the sampling loop.
- The sampling loop, Codex's loop around each model request, retries a 429 only when the response carried a Retry-After header, given in seconds or as an HTTP date. Codex waits until that time, sends the request again, and does this at most stream_max_retries times (5 by default), showing Reconnecting... 1/5, 2/5 and so on while it waits.
- On Codex's built-in OpenAI provider, which streams over WebSockets, Codex skips the first Reconnecting... line, and when those retries run out it falls back to HTTPS and starts counting again, so the same 429 can get about twice as many retries. A custom provider stays off WebSockets unless it sets supports_websockets, so for the Router One block below stream_max_retries is the whole budget.
- A 429 without Retry-After ends the turn at once: no Reconnecting... lines, just the message.
- Both settings belong to a custom provider, under [model_providers.<id>], and Codex caps each at 100. Raising stream_max_retries only adds attempts for 429s that carry Retry-After.
- OpenAI's Codex configuration reference (checked 2026-10-17) lists the same defaults: 4 for request_max_retries and 5 for stream_max_retries.

## Which 429s end in this message

Codex reads the error object in a 429's JSON body before it picks a message. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17):

| What the 429 body carries | What Codex prints | Retried by Codex |
| --- | --- | --- |
| error.type usage_limit_reached (a ChatGPT plan's usage limit) | A message that starts `You’ve hit your usage limit`, or another that names a usage limit, your workspace's credits or a spend cap | No |
| error.type usage_not_included | A message that starts `To use Codex with your ChatGPT plan, upgrade to Plus` | No |
| error.type insufficient_quota, or error.code insufficient_quota, credit_balance_exhausted, organization_spend_limit_exceeded, project_spend_limit_exceeded or organization_usage_limit_exceeded | `Quota exceeded. Check your plan and billing details.` | No |
| error.code flex_unavailable | `Flex capacity unavailable.` | No |
| Anything else | `exceeded retry limit, last status: 429 Too Many Requests`, plus `, request id: …` when a request-id header is present | Only when Retry-After is present, at most stream_max_retries times |

## Through Router One: whose 429 was it?

Codex prints the same line whoever sent the 429, so read Dashboard → Logs for the time of the error. A 429 that has a row there came back from upstream after the gateway's retries. A gateway limit on your key, your account, or your account's use of one model refuses the request before any model is called: its 429 has no row and recurs at the same rate while your traffic stays the same. A streamed request that hit an upstream limit before any output can also come back without a row, so a 429 without a row that comes in bursts and clears on its own points upstream too. Then:

- A row in Logs: the model's upstream limit was still in force after the gateway's retries. Send the prompt again later, run fewer Codex sessions on that model at once, or switch the model line to another model whose /models page lists POST /v1/responses.
- No row, at the same rate every time: a gateway limit on the key or the account. Spread the work out, move a noisy workload to a key of its own, or have the limit raised (next section).
- No row, in bursts that clear on their own: treat it as upstream and send the prompt again later.
- Keep the request id Codex printed, and quote it if you write to support@router.one.

## Raising a gateway limit

Router One's request and token limits on a key and on an account are platform defaults, not settings you change in the dashboard. To have them raised, email support@router.one with the account ID, the key, and the expected peak requests and tokens per minute; upstream capacity still applies above the gateway limit. A second key isolates a noisy workload from the first key's own limit, but keys of one account still share the account-level limit.

## Set up Codex with Router One

Run the one-click command with your Router One key. It installs Codex CLI if it is missing, backs up an existing config.toml, writes the configuration shown in the next section (provider router, env_key = ROUTER_ONE_API_KEY), saves the key in your shell profile and sends one test request. On Windows, use the PowerShell line.

`terminal`

```bash
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
```

## The config.toml the setup writes

The [model_providers.router] block is also where request_max_retries and stream_max_retries go if you change them; the one-click setup leaves both at Codex's defaults. Keep the top-level model = "gpt-5.6-sol" and model_provider = "router" lines above the first [table] header, and keep wire_api = "responses" and env_key = "ROUTER_ONE_API_KEY" in the block. This is the file the one-click install writes:

`~/.codex/config.toml`

```toml
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"
```

## A different message: ChatGPT sign-in limits

With ChatGPT sign-in, Codex reports a plan's limits with messages of their own. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), a usage limit prints a message that starts `You’ve hit your usage limit`, or another that names a usage limit, your workspace's credits or a spend cap, and Codex does not retry it. A model your ChatGPT sign-in cannot use is refused with a different reply, covered in the model-not-supported guide (https://router.one/codex-model-not-supported). A Codex session that uses Router One as its model provider sends its requests to https://api.router.one/v1 with your Router One key, not through the ChatGPT sign-in; Codex CLI in China (https://router.one/codex-china) has the full setup.

## FAQ

### Is "exceeded retry limit" a Router One error?

No. It is Codex's own message for a 429 it has stopped retrying, whichever server sent the 429. With Router One as the provider, Dashboard → Logs tells you whose 429 it was: a 429 that has a row there came back from upstream after the gateway's retries.

### Why didn't Codex retry the 429?

Because the response carried no Retry-After header. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), Codex retries a 429 only in its sampling loop and only when Retry-After tells it how long to wait; the HTTP-level retries (request_max_retries) never cover a 429. Send the prompt again once the limit has had time to reset, and check Dashboard → Logs to see whose limit it was.

### Will raising stream_max_retries or request_max_retries fix it?

Rarely. stream_max_retries adds attempts only for 429s that carry Retry-After, request_max_retries does not apply to a 429 at all, and Codex caps both at 100 (per the openai/codex source, rust-v0.163.0, checked 2026-10-17). More retries do not lift the limit itself: lower the load, or have a gateway limit on your key or account raised.

### The message says 401 Unauthorized or 503 Service Unavailable, not 429. Same fix?

No. Per the openai/codex source (rust-v0.163.0, checked 2026-10-17), Codex builds this message in its 429 handling, so 401 and 503 never appear after "last status". A 503 gets a different message: with the server_is_overloaded code it reads "Selected model is at capacity. Please try a different model." (see https://router.one/codex-model-at-capacity); with the slow_down code it reads "rate limit exceeded" followed by the server's message; any other 503 gets a message that starts "unexpected status 503 Service Unavailable". Older releases, rust-v0.46.0 for example, also ended a retried 401 or 503 with "exceeded retry limit", so update Codex and read the new message. Through Router One, a 401 means the gateway rejected the key Codex sent: check that ROUTER_ONE_API_KEY in the shell that starts Codex holds your current key and that the key is still active in Dashboard → API Keys. If the variable is unset or empty, Codex sends no request and instead prints a message that starts "Missing environment variable".

### Does a second API key get around the limit?

Only the per-key part. A second key isolates a noisy workload from the first key's own limit, but keys of one account still share the account-level limit; if that is the one you hit, ask support to raise it.

### How do I get a higher limit?

Email support@router.one with the account ID, the key, and the expected peak requests and tokens per minute. Router One's limits on a key and on an account are platform defaults rather than dashboard settings, and upstream capacity still applies above the gateway limit.

### Does this setup work from Mainland China?

Yes. The gateway is reachable from Mainland China without a VPN, and the configuration is the same as anywhere else: the same config.toml and the same ROUTER_ONE_API_KEY variable. A 429 reads the same way too: check Dashboard → Logs first.

## See also

- Codex model not supported fix: https://router.one/codex-model-not-supported
- Codex model at capacity: https://router.one/codex-model-at-capacity
- Codex CLI in China: https://router.one/codex-china
- Codex Responses API: https://router.one/codex-responses-api
- Error codes reference: https://router.one/llm-api-error-codes
- 429 deep-dive guide: https://router.one/blog/llm-api-429-rate-limit-fix
- insufficient_quota fix: https://router.one/openai-insufficient-quota
- Automatic fallback: https://router.one/llm-fallback
- CLI setup guide: https://router.one/docs/guides/cli-setup
- Codex configuration reference: https://developers.openai.com/codex/config-reference
- Canonical page: https://router.one/codex-exceeded-retry-limit
- Models and per-model token rates: https://router.one/models (markdown: https://router.one/models.md)
- Pricing: https://router.one/pricing
- API docs (markdown): https://router.one/docs.md
- Company facts: https://router.one/facts/company.md
