Error codes
Error structures and codes returned when an API call fails.
Check the protocol format first
OpenAI- and Anthropic-style errors expose a string in error.code. Gemini-style errors use a numeric HTTP status in error.code; when troubleshooting, also check error.status, error.message, and X-Request-Id.
Error formats
Chat Completions, Responses, Codex Search, Images Generations, and OpenAI model lists use OpenAI-style errors.
{
"error": {
"message": "Insufficient balance. Recharge and try again.",
"type": "billing_error",
"code": "insufficient_balance",
"request_id": "req_..."
},
"request_id": "req_..."
}Anthropic Messages, Count Tokens, and the Anthropic model list use Anthropic-style errors.
{
"type": "error",
"error": {
"type": "authentication_error",
"message": "missing API key",
"code": "api_key_missing"
}
}Gemini GenerateContent, streamGenerateContent, and the Gemini model list use Google-style errors.
{
"error": {
"code": 400,
"message": "api_key_conflict",
"status": "INVALID_ARGUMENT"
},
"request_id": "req_..."
}Common gateway errors
The table below lists string error codes used by the gateway and in OpenAI- or Anthropic-compatible responses. Gemini responses do not put these values in error.code.
| String error code | HTTP | Stage | Meaning |
|---|---|---|---|
api_key_missing | 401 | Authentication | The user API key was not provided in the protocol's required location. |
api_key_invalid | 401 | Authentication | The user API key does not exist or is invalid. |
api_key_disabled | 403 | Authentication | The user API key is disabled. |
api_key_conflict | 400 | Authentication | Multiple user-key headers were sent with different values. |
unsupported_header | 400 | Request header | A header is unsupported or malformed, such as multiple Idempotency-Key values or an invalid anthropic-version. |
unsupported_parameter | 400 | Request body | A non-empty previous_response_id is not currently supported; send the complete Responses context instead. |
insufficient_balance | 402 | Balance | The user's balance is insufficient to start a model call. |
user_not_found | 404 | Balance | The account state is abnormal; contact the administrator. |
request_body_too_large | 413 | Request body | The request body exceeds the gateway limit. |
invalid_request_body | 400 | Request body | The JSON or request structure is invalid. |
model_required | 400 | Request body | The required model name is missing. |
model_not_found | 404 | Dispatch | The model does not exist or is unavailable for the current entry. |
stream_not_supported | 400 | Request body | The current path does not support stream=true in the request body. |
gateway_concurrency_exceeded | 429 | Concurrency | The gateway's global concurrency limit has been reached. |
user_concurrency_exceeded | 429 | Concurrency | The current user's concurrency limit has been reached. |
upstream_not_configured | 502 | Upstream | No eligible upstream candidate is configured. |
upstream_cooling_down | 503 | Upstream | The upstream is in a cooldown period. |
upstream_concurrency_exceeded | 429 | Upstream | All available upstream accounts are currently at their concurrency limit. |
upstream_unavailable | 502 | Upstream | Multiple upstream candidates failed and the service is still unavailable. |
upstream_network_error | 502 | Upstream | The connection to the upstream failed. |
upstream_auth_failed | 502 | Upstream | Upstream authentication failed. |
upstream_access_denied | 502 | Upstream | The upstream denied access. |
upstream_quota_exceeded | 429 | Upstream | The upstream account hit a quota or billing limit; it may recover through cooldown and follows 429 retry semantics. |
upstream_rate_limited | 429 | Upstream | The upstream returned a rate-limit response. |
upstream_timeout | 504 | Upstream | The upstream request timed out. |
upstream_server_error | 502 | Upstream | The upstream returned a 5xx service error. |
upstream_model_unavailable | 502 | Upstream | The upstream reported that the model is unavailable. |
upstream_invalid_request | 400 | Upstream | The upstream rejected the request parameters. |
upstream_bad_status | 502 | Upstream | The upstream returned an unmapped non-2xx status. |
upstream_bad_response | 502 | Upstream | The upstream response could not be processed according to the protocol. |
upstream_stream_read_failed | 502 | Upstream | The upstream streaming response was interrupted. |
client_aborted | 499 | Client | The client disconnected. |
usage_missing | 502 | Settlement | The upstream response has no usage and does not meet the safety conditions for estimation. |
usage_invalid | 502 | Settlement | The usage fields are malformed and the response cannot safely use a conservative estimate. |
billing_calculation_failed | 500 | Settlement | The gateway failed to calculate billing. |
duplicate_request | 409 | Pre-check / settlement | The request is being processed or has already been processed, including a matching Idempotency-Key. |
billing_settle_failed | 500 | Settlement | The gateway failed to settle billing. |
response_too_large | 502 | Response | The upstream response body exceeds the gateway limit. |
internal_error | 500 | Internal | An internal gateway error occurred. |
Handling errors by stage
Last updated on