> For the complete documentation index, see [llms.txt](https://docs.kontinent.ai/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kontinent.ai/features/errors.md).

# Handling errors

Errors are always OpenAI-shaped:

```json
{ "error": { "message": "...", "type": "...", "code": "..." } }
```

## Status reference

| HTTP | `code`                  | `type`                  | Meaning / client action                                                                                                                                                                                          |
| ---- | ----------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `invalid_request`       | `invalid_request_error` | Malformed body, over 2 MiB, or missing `model`.                                                                                                                                                                  |
| 401  | `invalid_api_key`       | `invalid_request_error` | Bad or revoked key: **do not retry**.                                                                                                                                                                            |
| 402  | `insufficient_credits`  | `insufficient_quota`    | Balance at or below 0: top up, then retry.                                                                                                                                                                       |
| 403  | `segment_not_permitted` | `invalid_request_error` | Every candidate provider excludes your organization's registered usage segment by contract: **do not retry**, choose a model from another provider.                                                              |
| 404  | `model_not_found`       | `invalid_request_error` | Unknown or disabled model id.                                                                                                                                                                                    |
| 429  | `rate_limit_exceeded`   | `rate_limit_error`      | Per-key RPM hit: back off (sliding 60 s window).                                                                                                                                                                 |
| 429  | `upstream_rate_limited` | `rate_limit_error`      | Provider throttled us: retry with backoff.                                                                                                                                                                       |
| 500  | `internal_error`        | `api_error`             | Gateway bug: retriable.                                                                                                                                                                                          |
| 502  | `upstream_auth_error`   | `api_error`             | Provider rejected **our** credentials: our problem.                                                                                                                                                              |
| 502  | `upstream_error`        | `api_error`             | A provider **answered** and the answer was unusable: a 5xx, or (on a non-streaming request) a 2xx whose body could not be read, translated, or fit under the 32 MiB cap. Retriable, and worth routing elsewhere. |
| 503  | `no_provider_available` | `api_error`             | No provider could be **reached** at all. Transient on our side: retry as-is.                                                                                                                                     |

{% hint style="warning" %}
**On a streaming request these codes only apply before the first byte.** Once a stream has started the status is `200` and cannot be changed, and the codes from the table are not replayed in-stream: whatever went wrong is announced as a terminal stream error with `error.code: "upstream_error"`. On `/v1/chat/completions` that is a final chunk carrying a top-level `error` and `finish_reason: "error"`, with no `[DONE]` after it; on `/v1/responses` it is a `response.failed` event whose response object carries `status: "failed"` and the `error`. Both keep whatever output was already generated. A client that only inspects HTTP status will read a truncated answer as a complete one. See [Streaming](/features/streaming.md#failure-mid-stream).
{% endhint %}

{% hint style="info" %}
`502` and `503` look similar and mean different things. `502` says a specific provider is broken — a fallback or another model may well work right now. `503` says nothing in the chain answered, which is usually a network or credential problem on our side and affects every model of that provider at once; retrying the same request shortly is the right response.
{% endhint %}

## Passthrough errors

Upstream 4xx bodies that are already OpenAI-shaped (for example, provider-side validation of your parameters) are **passed through with their original status** rather than rewrapped.

## Retry guidance

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th></th></tr></thead><tbody><tr><td><h4><i class="fa-rotate" style="color:$primary;">:rotate:</i></h4></td><td><strong>Retriable</strong></td><td><code>429</code>, <code>500</code>, <code>502 upstream_error</code>, <code>503 no_provider_available</code>. Use exponential backoff with jitter.</td></tr><tr><td><h4><i class="fa-ban" style="color:$primary;">:ban:</i></h4></td><td><strong>Not retriable as-is</strong></td><td><code>400</code>, <code>401</code>, <code>403</code>, <code>404</code>. Fix the request or the key first. For <code>403</code>, choose a model from another provider. <code>402</code> is retriable only after a top-up.</td></tr></tbody></table>

## Common cases

<details>

<summary><code>404 model_not_found</code> on a model you can see in the dashboard</summary>

The id must be in `provider/model` form, and the model must be enabled for your organization. Confirm the exact id with `GET /v1/models`: that endpoint returns only what your organization can actually call.

</details>

<details>

<summary><code>400 invalid_request</code> with a request that works against OpenAI</summary>

Check the body size (the cap is 2 MiB) and that `model` is present. Provider-side parameter validation is passed through unchanged, so the message in the body comes straight from the upstream provider.

</details>

<details>

<summary>A stream that ends without <code>[DONE]</code></summary>

Failover only happens before the first byte. After that the status code is already `200`, so an upstream failure arrives **as a chunk**: a top-level `error` object plus `finish_reason: "error"`, and no `[DONE]`. Treat it as a retriable error on your side, and remember that the tokens generated so far are billed. See [Streaming](/features/streaming.md).

</details>

## Related

{% content-ref url="/pages/lu40tWXSSYv1E99p9B1Z" %}
[Rate limits & credits](/features/rate-limits.md)
{% endcontent-ref %}

{% content-ref url="/pages/i153gepDW64lHSqf4PxJ" %}
[Authentication](/overview/authentication.md)
{% endcontent-ref %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kontinent.ai/features/errors.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
