Errors
Errors come back in OpenAI's body shape with a useLLM-specific code. The code determines the HTTP status and whether the request falls through to a fallback model.
Body shape
{
"error": {
"message": "Human-readable description.",
"type": "<code>",
"code": "<code>"
}
}type and codeare always the same string — kept aligned with OpenAI's body so existing SDK error handling works without changes.
Code reference
| Code | Status | Retryable / fallback? | Meaning |
|---|---|---|---|
auth_missing | 401 | no | Authorization header missing. |
auth_invalid | 401 | no | Bearer token didn't match any gateway key, or the key is revoked. |
invalid_request | 400 | no | Request body failed validation, or the provider rejected it as a 400. |
rate_limited | 429 | yes — consumes retries, then falls back | Provider returned 429. Configure retries + fallbacks on the route to soak up bursts. |
quota_exceeded | 429 | no | Your useLLM plan's monthly routed-request limit is reached. Upgrade on /billing. |
timeout | 504 | yes | Provider call exceeded the route's timeoutMs. |
provider_auth | 502 | no | Provider returned 401/403 — your provider key was rejected. Rotate on /providers. |
provider_unavailable | 502 | yes | Provider returned a 5xx or the network call failed. |
no_provider_key | 400 | no (within an attempt; falls through to next provider in the chain) | No active provider connection for the resolved provider. Add one on /providers. |
route_not_found | 400 | no | Model id matched an alias whose configuration is malformed. |
model_not_supported | 400 | no | Unknown direct model id (didn't match any provider prefix) and no alias matched either. |
not_implemented | 501 | no | A feature you used isn't implemented yet — currently only streaming. |
internal | 500 | no | Unexpected gateway failure. Check the gateway logs. |
Retryability vs. fallback
Retryableerrors get the retry count from the route config applied to the current (provider, model) attempt. Once retries are exhausted the gateway falls through to the next entry in the fallback chain. Non-retryable errors surface immediately — there's no point retrying a 400 or trying a different provider for an authentication problem.
quota_exceeded is special-cased as non-retryable because the next attempt would hit the same limit anyway.
Operational headers on failures
Even on failure the gateway writes a metadata-only log row, so rejections show up in the dashboard with their HTTP status and errorCode. That makes it easy to spot a spike of provider_auth after a key rotation, or quota_exceeded just before a renewal.