Skip to main content
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

Any other 4xx is the provider’s own error, passed through. See 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.
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.
/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.

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 (403).
  3. Usage limits (429).
  4. Input 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 rule refuses the model named in the request. The message says which kind of rule it was. A block rule:
An allow list that doesn’t include the model, naming up to five models the key can call instead:
Retrying won’t help. Pick an allowed model, or ask your operator to change the rule.

422 Unprocessable Entity

A guardrail 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.

429 Too Many Requests

A usage limit on your key, user, or group is reached. The message says when it resets:
Weekly and monthly limits name the reset date instead, such as on November 1. An all-time limit never resets, and says so:
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. 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 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.