# Errors > The error envelope, the stable codes, and what to do about each. Section: Developers. Web page: https://docs.katara.com/developers/errors/ Errors use the OpenAI envelope: ```json { "error": { "message": "…", "type": "insufficient_quota", "code": "insufficient_quota", "param": null, "request_id": "req_…" } } ``` Branch on `code`. The `message` is for people and may change. Every response, success or error, has an `x-katara-request-id` header, repeated as `x-request-id` and `request-id` so the OpenAI and Anthropic SDKs pick it up; error bodies carry it as `request_id`. Include it when you write to support. The statuses follow the SDKs' retry rules. The OpenAI and Anthropic SDKs retry 408, 409, 429 and every 5xx, and obey an `x-should-retry` header. Katara answers with a 429 or a 5xx only when waiting can help, and sends `x-should-retry: false` on the answers a retry cannot change. Katara never answers 502 or 504: a failure behind Katara is a 500 and a slow model a 503, so the error body always reaches you. A `402` with an `error` body is a refusal; a `402` that carries `accepts` is an [x402 payment challenge](https://docs.katara.com/developers/x402.txt). | HTTP | code | Meaning | What to do | |---|---|---|---| | 400 | `invalid_request` | The body is malformed. | Fix the request. | | 400 | `model_requires_x402` | The request names `katara/cortex-genius` or `katara/cortex-smart` with a key or from a Katara app. Those models are sold only per request with x402. `param` is `model`. | Name `katara/cortex`, or send the request without a key and pay with [x402](https://docs.katara.com/developers/x402.txt). | | 400 | `model_requires_usdc` | The key pays with account credits, and the request can only be served for USDC. | Use a key that pays with USDC. | | 400 | `context_length_exceeded` | The request is longer than the context window of every model that could read it; nothing was sent to a model. The message names the largest window. `param` is `messages`. | Shorten or summarise the conversation. | | 400 | `invalid_web_search` | `katara_web_search` is malformed, or names both `allowed_domains` and `blocked_domains`. `param` is `katara_web_search`. | Send one domain list. | | 400 | `invalid_value` | A field has a value Katara cannot serve, such as a malformed custom tool. `param` names the field. | Fix the field. | | 400 | `feature_not_supported` | The model does not support what the request asks for: tools, structured output, reasoning, a `tool_choice` outside its contract, or a parameter it does not act on (`param` names the field). A parameter left at its default is accepted and dropped. | Check `capabilities`, `tool_contract` and `supported_params` on `/v1/models`. | | 401 | `invalid_api_key` | Missing or unknown key. | Create a key in the portal. | | 402 | `insufficient_credits` | The key pays with account credits, and the available credits cannot cover the request's maximum cost. Not retried: the answer carries `x-should-retry: false`. | Add credits in **Billing** in the portal, or lower `max_tokens`. | | 402 | `insufficient_quota` | The key pays with USDC, and its spendable balance is below the request's maximum cost. Not retried: the answer carries `x-should-retry: false`. `spendable_usdc` and `max_charge_usdc` say how far short it is. | Add USDC, raise the budget cap, or lower `max_tokens`. | | 403 | `account_suspended` | The account behind the key is suspended. | Contact support. | | 403 | `billing_suspended` | Credit billing is paused for the account. | Contact support. | | 403 | `community_off` | Only Katara Community could serve the request, and it is turned off by the request (`param` is `katara.community`), the key or the account. | Turn Katara Community on, or send a request a managed model can serve. | | 403 | `wrong_environment` | A Live key was sent to the Test network's address under `https://api.katara.com/test`. | Send it to `https://api.katara.com/v1`: the key decides the network. | | 404 | `model_not_found` | An embeddings request named a model Katara does not serve. Chat, Messages, Responses and image requests accept any model name. | Use the model named in [Embeddings](https://docs.katara.com/developers/embeddings.txt). | | 404 | `not_found` | No API route at that path. | Check the path against the API reference. | | 405 | `method_not_allowed` | The path exists but not for that HTTP method. | Use the documented method. | | 413 | `request_too_large` | The body is over 32 MB, or 4 MB for a request paid per call. | Upload large files through `/v1/files` and refer to them by id. | | 413 | `media_too_large` | The images, recordings and documents in one request add up to more than 20 MB decoded. | Send fewer or smaller files, or upload them through `/v1/files`. | | 429 | `provider_rate_limited` | Every vendor that could serve the request is rate limiting. Nothing was charged. | Retry after `Retry-After`, which repeats the vendor's own wait, up to 60 seconds. | | 500 | `internal_error` | Something failed on our side. | Retry; report the request id if it persists. | | 500 | `provider_output_invalid` | Every provider tried answered with something Katara refused to deliver: a reply with no text and no tool call, a malformed tool call, tool syntax left in the text, a runtime fault, a reply stuck repeating itself, or a stop the runtime did not mean. Managed models are held to the same rule. Nothing was charged. A [web search](https://docs.katara.com/developers/tools.txt#web-search) request whose model searched and wrote no answer ends the same way; its `katara` object lists the searches that ran, and only a Katara Community reply that asked for the search is charged. | Retry after `Retry-After`. | | 500 | `provider_rejected_request` | Every provider tried refused the request body itself: a conversation history its runtime will not render, or a field it cannot take. Nothing was charged and a retry of the same request will fail the same way, so the answer carries `x-should-retry: false`. | Check the history and parameters, then send a corrected request. | | 503 | `provider_overloaded` | Every vendor that could serve the request is overloaded or unavailable, some perhaps rate limiting. Nothing was charged. | Retry after `Retry-After`. | | 503 | `funding_pending` | Your USDC is still being moved into your prepaid balance. Nothing was charged. | Retry after `Retry-After`. | | 503 | `no_capacity` | No candidate could serve the request right now. | Retry after `Retry-After`. | | 503 | `storage_unavailable` | File storage for `/v1/files` is unavailable. | Retry later. | | 503 | `test_network_unavailable` | A Test key's request did not reach the Test network. Nothing was charged. | Retry after `Retry-After`. | | 503 | `upstream_timeout` | No candidate started its reply within its time limit, as a hard question sometimes does. Nothing was charged. | Retry after `Retry-After`. | ## Streams A stream that fails after content was sent ends with an error chunk, then `[DONE]`: ``` data: {"error":{"message":"stream interrupted by provider failure; delivered tokens are not billed without a verified receipt","type":"server_error","code":"stream_interrupted"}} ``` Two codes can appear there. `stream_interrupted` means the provider stopped or disconnected. `provider_output_invalid` means the provider's reply failed validation, for example a tool call that could not be delivered, a reply that kept repeating itself, or a reply that ended with nothing delivered. In both cases nothing is charged for that attempt. Send the request again. A reasoning model's thinking arrives under `reasoning_content` in the message or the delta, before the answer. It is shown and it counts as output tokens at the model's output price, but it is never the answer: a reply that only reasoned and never answered is refused like an empty one. ## Agent runs paid from a wallet The product API refuses a budget or a run when the wallet paying for it cannot: `wallet_required`, `wallet_insufficient_funds`, `wallet_unpaid_limit`, `wallet_payment_failed` and `wallet_unavailable`. [Pay for runs from your wallet](https://docs.katara.com/products/wallet-budgets.txt#refusals) says what each means. A run paid per run with x402 has its own refusals, listed under [run errors](https://docs.katara.com/developers/x402.txt#run-errors). ## Wallet-paid requests If the model quoted for a Cortex request paid per call fails before delivering anything, the next model answers under the same payment. When that model costs more than the payment covers, the answer is a fresh `402` for it instead: sign it and retry, the first authorization expires unused. Each address may hold a limited number of unpaid quotes; past it the answer is `429 quote_rate_limited` with `Retry-After`. [Pay per request with x402](https://docs.katara.com/developers/x402.txt#errors) lists the payment errors and those of the Responses API.