> ## Documentation Index
> Fetch the complete documentation index at: https://docs.codex.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Errors & Retries

> How Codex reports errors, which ones are safe to retry, and how long to wait

## How Errors Arrive

Codex is a GraphQL API, so most errors come back in the `errors` array of an otherwise normal response — **HTTP 200 with an `errors` key**, not an HTTP error status. Only authentication and rate limiting fail at the HTTP layer.

```json theme={null}
{
  "errors": [
    {
      "message": "The requested resources are over capacity. Retry in about 30 seconds — retrying sooner will be throttled.",
      "extensions": {
        "code": "OVER_CAPACITY",
        "retryAfterSeconds": 30
      }
    }
  ]
}
```

<Warning>
  If your error handling only inspects HTTP status codes, it will treat these as successful responses. Always check whether the body contains an `errors` array.
</Warning>

## Which Errors to Retry

There is one field to watch: **if an error carries `extensions.retryAfterSeconds`, wait that many seconds before retrying that request.** On rate-limited responses the same value is also sent as the standard `Retry-After` header, so most HTTP client libraries will honor it without any code from you.

| Code                            | HTTP status | Meaning                                    | Retry                                                    |
| ------------------------------- | ----------- | ------------------------------------------ | -------------------------------------------------------- |
| `TOO_MANY_REQUESTS`             | 429         | You exceeded your plan's rate limit        | After `retryAfterSeconds`, or your own backoff if absent |
| `OVER_CAPACITY`                 | 200         | We're briefly over capacity and scaling up | After `retryAfterSeconds`                                |
| `UNAUTHENTICATED` / `FORBIDDEN` | 401 / 403   | Bad or missing credentials                 | No — fix the credentials                                 |
| Everything else                 | 200         | Unexpected failure on our side             | Not automatically — see below                            |

### Rate limited

A `TOO_MANY_REQUESTS` error means you exceeded your plan's per-second rate limit. When we can tell you exactly when the limit lifts, we do, via `retryAfterSeconds` and the `Retry-After` header.

A 429 **without** `retryAfterSeconds` means your request budget is momentarily empty rather than your account being throttled — capacity typically returns within a second. Back off on your own schedule and retry; don't retry immediately in a tight loop.

See [Rate Limits & Connection Limits](/concepts/rate-limits) for the limits themselves.

### Over capacity

An `OVER_CAPACITY` error means the data your query needs is temporarily under more load than it can serve, and we're scaling up. It is not caused by anything wrong with your request — the same query will succeed once you retry.

These arrive as HTTP 200 with the error in the body. Retry after `retryAfterSeconds` (currently 30). Retrying sooner is likely to be throttled and slows the recovery for everyone.

### Everything else

Unexpected errors return a generic message with an error code:

```json theme={null}
{
  "errors": [
    {
      "message": "Something went wrong. Error Code: 1a2b3c4d5e6f7890"
    }
  ]
}
```

Don't retry these automatically — the same request will usually fail the same way. Include that error code when you [contact support](mailto:support@codex.io) or ask on [Discord](https://discord.gg/9ZB7zcWuBY); it lets us find the exact failure in our logs.

## Retry Strategy

<Info>
  Fixed retry intervals are the most common cause of prolonged rate limiting. If your interval is shorter than the penalty window, every retry lands inside it and extends the problem.
</Info>

A retry policy that works well against Codex:

1. **Honor `retryAfterSeconds` whenever it's present.** It's computed from the actual condition — it isn't a guess, and it overrides whatever interval you'd otherwise use.
2. **Otherwise use exponential backoff with jitter.** Jitter matters if you run multiple workers: without it they synchronize and retry in a thundering herd.
3. **Cap your retries.** Three to five attempts is plenty; past that the condition needs attention rather than another request.
4. **Don't retry non-retriable errors.** Auth failures and malformed queries will fail identically every time.

If you're hitting rate limits often enough that retry behavior matters, [Optimization](/concepts/optimization) covers how to reduce request volume — usually the better fix.
