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

# Errors

> What each gateway error means, whether retrying helps, and who can fix it

The gateway answers errors in the format of the API you called, so your SDK raises its usual
exception and shows the gateway's message. An error comes from one of two places: one of the
gateway's own checks, or the provider, whose errors pass through.

## At a glance

| Status | What it means | Retry? | Who fixes it |
| - | - | - | - |
| **400** | The gateway can't accept the request as sent | No | Caller |
| **401** | The API key is missing, unknown, or disabled | No | Caller |
| **403** | A model access rule doesn't let this key call the model | No | Operator |
| **422** | A guardrail blocked the request or the response | No, change the content | Caller or operator |
| **429** | A usage limit is reached, or the provider rate-limited the call | Not for a usage limit | Operator |
| **502** | The provider failed or dropped the connection | Yes, with backoff | Provider |
| **503** | The gateway can't serve the request right now, or isn't set up to | Depends on the message | Operator |
| **504** | The provider didn't answer in time | Yes, with backoff | Provider |

Any other `4xx` is the provider's own error, passed through. See
[Errors from the provider](#errors-from-the-provider).

## Error format

`/v1/messages` answers in the Anthropic shape. `/v1/responses` and `/v1/embeddings` answer in the
OpenAI shape. `GET /v1/models` follows the path you call: `/anthropic/v1/models` or
`/openai/v1/models`, and on the bare `/v1/models`, the Anthropic shape when the request carries
Anthropic SDK headers and the OpenAI shape otherwise.

<CodeGroup>
  ```json Anthropic theme={null}
  {
    "type": "error",
    "error": {
      "type": "rate_limit_error",
      "message": "You've reached the daily limit. Your limit will reset tomorrow. If this is unexpected, contact your administrator."
    }
  }
  ```

  ```json OpenAI theme={null}
  {
    "error": {
      "message": "You've reached the daily limit. Your limit will reset tomorrow. If this is unexpected, contact your administrator.",
      "type": "rate_limit_error",
      "param": null,
      "code": null
    }
  }
  ```
</CodeGroup>

The `type` follows the status code: `invalid_request_error` for 400 and 422,
`authentication_error` for 401, `permission_error` for 403, `not_found_error` for 404,
`rate_limit_error` for 429, and `api_error` for 5xx. `param` and `code` are always `null`.

<Note>
  `/v1/images/generations` doesn't use the OpenAI shape for errors yet. Its error
  body is `{"detail": ...}`, with the message under `detail`. A guardrail block
  there carries an object with the guardrail's `type`, `stage`, and `reason`.
</Note>

## Which check fails first

The gateway checks a request in this order and stops at the first failure, so this decides which
error a caller sees when several apply:

1. **API key** (`401`).
2. **[Model access](/gateway/model-access)** (`403`).
3. **[Usage limits](/gateway/budgets-and-limits)** (`429`).
4. **Input [guardrails](/gateway/guardrails)** (`422`). Embeddings skip guardrails.
5. **Routing and the provider call**. A setup problem returns `503`, and the provider's own errors
   pass through.
6. **Output guardrails** (`422`), on responses that don't stream.

Everything before step 5 is refused before the request reaches a provider.

## 401 Unauthorized

The key is missing, isn't recognized, or has been disabled or deleted. The message starts with
`Missing API key.` or `Invalid API key.` Send the `sk-olga-` key your operator gave you, as
`Authorization: Bearer <key>` or in the `x-api-key` header.

## 403 Forbidden

A [model access](/gateway/model-access) rule refuses the model named in the request. The message
says which kind of rule it was. A block rule:

```text theme={null}
The model 'claude-opus-4' is not available through this gateway. If this is unexpected, contact your administrator.
```

An allow list that doesn't include the model, naming up to five models the key can call instead:

```text theme={null}
The model 'gpt-4o' is not available to this API key. Available models include: gpt-4o-mini. If this is unexpected, contact your administrator.
```

Retrying won't help. Pick an allowed model, or ask your operator to change the rule.

## 422 Unprocessable Entity

A [guardrail](/gateway/guardrails) blocked the request on its way in, or the response on its way
out. The message is the guardrail's reason, and it doesn't name the guardrail or the stage:

* PII: `Detected high-risk PII entities: US_SSN`
* Prompt injection: `Detected prompt injection attempt (score: 0.987)`
* Content safety: `Detected toxic content: insult=0.912 (threshold: 0.5)`

Retrying the same content gets the same answer. Remove the flagged content, or ask your operator to
review the guardrail. A response blocked on the way out was already generated, so its tokens still
count toward [usage limits](/gateway/budgets-and-limits).

## 429 Too Many Requests

A [usage limit](/gateway/budgets-and-limits) on your key, user, or group is reached. The message
says when it resets:

```text theme={null}
You've reached the daily limit. Your limit will reset tomorrow. If this is unexpected, contact your administrator.
```

Weekly and monthly limits name the reset date instead, such as `on November 1`. An all-time limit
never resets, and says so:

```text theme={null}
You've reached your usage limit. If this is unexpected, contact your administrator.
```

The gateway sends no `Retry-After`, and retrying fails the same way until the limit resets.
OpenAI and Anthropic SDKs retry a 429 automatically, so expect their retries to fail too. Ask your
operator to raise the limit.

A 429 with a different message is the provider's rate limit, passed through. That one clears with
backoff.

## 503 Service Unavailable

The message tells you which cause you hit. Some clear on their own and carry a `Retry-After`
header; the others need your operator.

| Message starts with | Cause | Retry-After | Fix |
| - | - | - | - |
| `gateway at capacity` | The gateway is at its concurrency cap | 1 s | Retry with backoff |
| `no upstream capacity for` | Too many calls in flight to one provider | 1 s | Retry with backoff |
| `The ... guardrail is still loading` | A guardrail's model is loading | 5 s | Retry shortly |
| `The gateway's database is unavailable` | The gateway's database didn't answer in time | 5 s | Retry shortly |
| `No API key is configured for` | The provider has no API key stored | None | [Connect providers](/gateway/connect-providers) |
| `Provider '...' is not configured` | A routing rule targets a provider that isn't there | None | [Route requests](/gateway/route-requests) |
| `The routing rule` | The matching rule can't serve this endpoint | None | [Route requests](/gateway/route-requests) |
| `No routing rule resolves requests` | No routing rule matches the request at all | None | [Route requests](/gateway/route-requests) |

`The routing rule` covers embeddings and image generation routed to a provider that isn't OpenAI or
Azure OpenAI, and embeddings matched by a model-based routing rule. The message names the rule's
target and the change to make.

## 502 Bad Gateway and 504 Gateway Timeout

A **502** means the provider answered with a `5xx` error, or closed the connection without
answering. The message is the provider's. A **504** means the provider didn't answer in time. Both
are worth retrying with backoff.

## 400 Bad Request

Right after the API key check, the gateway rejects a few requests it can't serve as sent:

* `Streaming image generation is not supported.` Send the image request without `stream`.
* On `/v1/embeddings`, a body that isn't a JSON object or doesn't name a `model`.

## Errors from the provider

The gateway passes a provider's `4xx` errors through with the provider's status code and message,
maps a provider's `429` to `429`, and maps any provider `5xx` to `502`. So a `403`, `404`, `422`,
or `429` can come from the provider as well as from the gateway. The message tells them apart: the
gateway's own messages are the ones quoted on this page.

The `type` is set from the status code, and the provider's own error `code`, such as OpenAI's
`insufficient_quota`, isn't kept. The provider's `Retry-After` header isn't forwarded.

## Streaming responses

A streamed request gets the same errors as any other, as long as they happen before the first
event: every check before the provider call, and any error the provider answers with up front. Once events have
started, the status is already `200`, so a failure partway through ends the stream early instead.

## Find a request in the logs

Send an `X-Request-ID` header with each request. The gateway uses it in its logs and as the
[Openlayer trace](/gateway/observability) ID, so your operator can find the exact request behind an
error. When you omit it, the gateway generates an ID but doesn't return it, so send your own if you
might need to trace an error.

<CodeGroup>
  ```python Python (OpenAI) theme={null}
  response = client.responses.create(
    model="gpt-4o-mini",
    input="Hello!",
    extra_headers={"X-Request-ID": "checkout-7f3a2c"},
  )
  ```

  ```bash cURL theme={null}
  curl https://your-gateway.example.com/v1/responses \
    -H "Authorization: Bearer sk-olga-..." \
    -H "X-Request-ID: checkout-7f3a2c" \
    -H "Content-Type: application/json" \
    -d '{"model": "gpt-4o-mini", "input": "Hello!"}'
  ```
</CodeGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.