Reliability

# Errors

Errors use the shape of the endpoint you called: OpenAI-style on Chat Completions, Responses and the other routes, Anthropic-style on `/v1/messages`. Every error carries a stable `code`; branch on it, not on the message.

**On this page**

- [Shapes](https://inference.dagon.so/docs/errors#shapes)
- [Types by status](https://inference.dagon.so/docs/errors#types-by-status)
- [Request errors (400, 404, 408, 413)](https://inference.dagon.so/docs/errors#request-errors-400-404-408-413)
- [Authentication (401, 403)](https://inference.dagon.so/docs/errors#authentication-401-403)
- [Billing (402)](https://inference.dagon.so/docs/errors#billing-402)
- [Limits and capacity (429, 503)](https://inference.dagon.so/docs/errors#limits-and-capacity-429-503)
- [Upstream and other](https://inference.dagon.so/docs/errors#upstream-and-other)

## Shapes

JSON

```json
// OpenAI-style
{ "error": { "message": "This key has no credit available. Add credits first.",
             "type": "billing_error", "param": null, "code": "insufficient_credits" } }

// Anthropic-style (/v1/messages, /v1/messages/count_tokens)
{ "type": "error",
  "error": { "type": "invalid_request_error", "message": "This key has no credit available. Add credits first.",
             "code": "insufficient_credits" } }
```

Errors from the gateway carry `x-gateway-request-id`; quote it when you contact support. `Retry-After` is set wherever retrying later can succeed. An error from the provider itself is passed through in its own shape; a provider's `401`, `402` or non-policy `403` becomes a `502`/`503` from the gateway, since it is never your billing problem.

## Types by status

| Status | OpenAI type | Anthropic type |
| --- | --- | --- |
| 400 | `invalid_request_error` | `invalid_request_error` |
| 401 | `auth_error` | `authentication_error` |
| 402 | `billing_error` | `invalid_request_error` |
| 403 | `permission_error` | `permission_error` |
| 404 | `not_found_error` | `not_found_error` |
| 409 | `invalid_request_error` | `api_error` |
| 413 | `invalid_request_error` | `request_too_large` |
| 429 | `rate_limit_error` | `rate_limit_error` |
| 451 | `unavailable_for_legal_reasons` | `api_error` |
| 503 | `provider_error` | `overloaded_error` |
| other | `provider_error` | `api_error` |

## Request errors (400, 404, 408, 413)

| Code | Meaning |
| --- | --- |
| `invalid_json`, `invalid_body` | The body is not a JSON object. |
| `unsupported_parameter` | A field the gateway does not forward (it names it in `param`), an unsupported tool or `tool_choice`, content stored upstream, or an `anthropic-beta`. |
| `web_search_not_supported` | Web search is billed per search upstream and is not available. |
| `missing_max_tokens`, `invalid_max_tokens`, `max_tokens_too_large` | Messages needs `max_tokens`; caps must be positive integers within the model's limit. |
| `invalid_n` | `n` must be 1 to 8, on chat only. |
| `unsupported_endpoint` | The model is not served on this endpoint; see its `endpoints`. |
| `model_not_found` | Unknown model id (404). List models with `GET /v1/models`. |
| `request_timeout` | The body did not arrive in time (408). |
| `request_too_large` | The body is over the limit (413); see [limits](https://inference.dagon.so/docs/rate-limits). |

## Authentication (401, 403)

| Code | Meaning |
| --- | --- |
| `missing_api_key` | No key was sent. |
| `invalid_api_key` | Unknown or revoked key. |
| `key_expired` | The key's expiry has passed. |
| `key_disabled` | The key or its account was deleted or disabled. |
| `session_not_allowed`, `session_required`, `invalid_session`, `session_expired` | Console session problems; see [passkeys](https://inference.dagon.so/docs/passkeys). |
| `key_suspended` | 403: an automatic safety suspension. See [Safety](https://inference.dagon.so/docs/safety). |
| `forbidden` | 403: this credential may not do that (a child managing children, a session deleting its account). |
| `reauth_required` | 403: log in with a passkey again before changing passkeys. |

## Billing (402)

| Code | Meaning |
| --- | --- |
| `payment_required` | No key: pay with [x402](https://inference.dagon.so/docs/x402) or send a key. |
| `insufficient_credits` | The key's available balance is below this request's hold. Add credit or lower the output cap. |
| `insufficient_funds` | A transfer between root and child is larger than what is available. |
| `paid_daily_cap_exceeded` | The account received $2,000 of paid credit in 24 hours. |
| `settlement_pending`, `duplicate_settlement`, `invalid_exact_svm_…` | x402 payment problems; see [x402 error codes](https://inference.dagon.so/docs/x402#error-codes). |

## Limits and capacity (429, 503)

| Code | Meaning |
| --- | --- |
| `too_many_requests` | Too many requests in flight for the key, the account, or (without credit) the client address. |
| `rate_limited` | An hourly limit was reached; see the message and Retry-After. |
| `too_many_open_checkouts` | Five unpaid checkouts are open on this key. |
| `service_busy` | The gateway is at capacity. Retry shortly. |
| `service_paused` | The gateway is temporarily not taking requests. |
| `upstream_unavailable` | No provider can take the request right now. |

## Upstream and other

| Code | Meaning |
| --- | --- |
| `upstream_unreachable` | 502: the provider could not be reached. Nothing is charged. |
| `upstream_failed` | 502: the provider failed while answering, or sent more than the request allows. |
| `upstream_timeout` | 504: the provider did not finish in time. |
| `request_cancelled` | 499: the client went away. |
| `location_blocked` | 451: the service is not offered where the request comes from. |
| `internal_error` | 500: a gateway fault. Quote the request id. |

Last updated 2026-11-07

[Previous **x402 pay per request**](https://inference.dagon.so/docs/x402) [Next **Rate limits**](https://inference.dagon.so/docs/rate-limits)
