Errors

Every error Gateway returns, in one place

Gateway errors share one JSON envelope, carry a stable code you can branch on, and tell you whether the failure came from Gateway or from the upstream provider. This page is the aggregate reference; each feature page covers its own errors in context.

Before you write retry logic, read what fails over: under a routing policy, Gateway already retries some of these failures on another route.

The error envelope

Model API errors (/v1/responses and every compatible surface) return:

1{
2 "error": {
3 "type": "invalid_request_error",
4 "message": "Project budget exceeded for '4f8b2c6e-9d1a-4e7a-b3f5-2c8d0a6e1b47'.",
5 "code": "project_budget_exceeded",
6 "param": "project_id",
7 "source": "gateway",
8 "provider": null
9 }
10}
  • type is the broad category (invalid_request_error, authentication_error, budget_exceeded, blocked_by_policy, rate_limit_error, not_found_error, provider_error, internal_error).
  • code is the specific, stable identifier. Branch on code, not on message text.
  • source is "gateway" when Gateway rejected the request itself and "provider" when the upstream provider failed; provider then names the vendor.

The Management API (/v1/keys, /v1/projects, /v1/routing-policies, /v1/customers) uses FastAPI’s {"detail": ...} shape instead, with structured codes on the cases worth branching on (for example 409 PROJECT_HAS_ACTIVE_API_KEYS).

Authentication: 401

codeMeaning
(none, invalid_request_error)Missing key, or a malformed Authorization header
invalid_api_keyKey unknown, expired, or inactive; also a management key used on model endpoints, or a model key used on /v1/keys

Payment and budgets: 402

codeScopeFix
budget_exceededOrganization credit balanceAdd credits, or upgrade off the free tier
payment_failedOrganization payment stateUpdate the payment method
project_budget_exceededProject hard limitRaise the project budget (changes take up to an hour to apply)
api_key_limit_exceededPer-key spend limitRaise limit or wait for the limit_reset window
(none, budget_exceeded)Embedded Routing customer budgetRaise the customer’s budget

Responses include remaining-headroom headers as limits approach: X-Credit-Balance-USD, X-Project-Budget-Remaining-USD / X-Project-Budget-Limit-USD, X-Key-Limit-Remaining-USD / X-Key-Limit-USD.

Invalid requests: 400

codeMeaning
model_requiredNo model and no routing policy resolved (or the resolved policy has no providers)
invalid_model_formatThe model string matched nothing; use provider/model
invalid_response_formatMalformed response_format / text.format (e.g. json_schema without a schema)
ambiguous_base_modelA bare model name matched several providers; qualify it
project_mismatchThe request’s project_id conflicts with a project-scoped key
unsupported_paramsThe chosen route can’t serve the request (tool calling, structured outputs, an input modality, or the requested service_tier)
capability_unavailableNo vendor for the model supports the requested capabilities
context_window_exceededProvider rejected the request as too large (source: "provider")
content_policy_violationProvider’s content policy blocked the request (source: "provider")
zdr_vendor_unavailableZero data retention is on and no ZDR-compliant vendor serves the model
fusion_config_required, fusion_stream_unsupported, fusion_unsupported_tools, fusion_routing_policy_unsupportedFusion constraints
web_search_unavailable, unsupported_web_search_engine, invalid_server_tool_parametersWeb search constraints
unknown_tagsA tag not defined for your org; list them with GET /v1/tags
unsupported_tool_typeThe request declares a tool type the resolved route cannot execute
unsupported_provider_native_toolA vendor-specific server tool such as web_search_20250305 was sent to a route on another vendor
openai_tool_search_requires_openaiOpenAI’s server-executed tool_search was sent on a request that cannot reach OpenAI’s Responses API (another provider’s model, default_routing, a vendor pin elsewhere, or an org policy excluding OpenAI). See OpenAI hosted tools
tool_search_stream_unsupportedOpenAI’s server-executed tool_search was sent with stream: true; it is served on non-streaming requests only
invalid_thinking_budgetthinking.budget_tokens was zero, negative, or not an integer
unsupported_reasoning_effortThe effort level is not one this route accepts. Read reasoning.effort_values from GET /v1/models
alias_not_supportedAn @alias/ model was sent to /v1/embeddings, /v1/images/generations, /v1/audio/*, or /v1/videos. Aliases resolve on the chat surfaces only
vendor_unavailableThe vendor or vendors pin names a vendor that cannot serve the model
conflicting_routing_policyThe request set both routing_policy_id and a routing policy id in model
customer_mismatchThe body customer conflicts with the customer a customer-scoped key is bound to

Policy and permission blocks: 403 and 422

StatuscodeMeaning
403customer_blocked, customer_pinned, customer_model_blocked, provider_blocked, model_blockedA blocklist rule matched; type is blocked_by_policy
403vendor_access_requiredThe model’s vendor is not enabled for your organization; the message names it. See Vendor access; type is blocked_by_policy
403model_not_allowedThe API key carries a model allowlist that excludes the requested model
403free_tier_model_not_allowedThe model is outside the free plan’s model list; add a payment method
422blocked_by_dlp_policyA DLP rule blocked the request
422pi_block_threshold and related pi_* codesPrompt injection protection blocked the request; type is blocked_by_pi_protection
400routing_policy_requires_customer, routing_policy_requires_projectThe named routing policy is scoped to a customer or a project that the request’s credentials do not resolve to

Not found: 404

codeMeaning
model_not_foundAn unknown model id; check GET /v1/models
vendor_not_foundAn unknown vendor id
customer_not_foundAn unknown Embedded Routing customer

Too large and too fast: 413 and 429

StatuscodeMeaning
413payload_too_largeInline base64 media over the per-modality cap (20 MB; 25 MB for audio). Send a URL reference instead
429(none, rate_limit_error, source: "provider")The upstream provider throttled the request. With a routing policy, this triggers failover before you ever see it
429(none, rate_limit_error, source: "gateway")A per-key rate limit you configured with rate_limit_rpm or rate_limit_tpm; the response carries Retry-After. Gateway sets no rate limits by default. See Rate limits

Provider failures: 5xx

codeMeaning
provider_authentication_failed (503)The credentials serving the route were rejected upstream; for BYOK, check your provider key
provider_account_restricted (503)The provider declined for account or billing reasons on the serving credentials
(none, 503)Transient provider failure or timeout. Retry, or let a Priority policy fail over
model_vendor_unhealthy (503)Gateway’s circuit breaker has the route marked unhealthy after repeated failures
internal_error (500)Unexpected Gateway error; retry, and contact support if it persists

What fails over

Under a Priority or Intelligent routing policy, some failures are retried on the next candidate route instead of being returned to you. That is why a request that failed on one vendor can come back answered by another, and why client-side retries on these statuses usually duplicate work Gateway already did. A direct model call, with no policy resolved, returns the failure as-is.

FailureFails over
Provider 429, 5xx, or a timeoutYes, to the next candidate route
Provider 402, or a provider 400 whose message names a billing or account gateYes. Once every candidate is exhausted, Gateway returns the branded provider_account_restricted rather than echoing the provider’s wording
Provider 404Yes, on the status alone. A model id you sent is resolved by Gateway before dispatch, so a 404 from upstream is an account or deployment problem rather than a bad request
A 400 content-policy refusalYes, to the next candidate whose model comes from a different author
A 200 that stops with empty content and no tool callsYes, to a different model author. Not classified on streams, and not classified when the request carried stop sequences
A 200 that violates a json_schema sent with strict: trueYes, to a different canonical model. Not classified on streams. See Structured outputs
Validation errors Gateway raises itself (400 to 404), credential 401 and 403, and a Gateway budget 402No

On the three 200-shaped cases, exhausting every candidate serves the last response received rather than converting it into an error, so you get the refusal or the schema-violating body. Each discarded attempt is billed at the route that ran it.

Errors during streaming

A streamed request is validated before the stream opens. If the first frame from the provider is an error, or Gateway rejects the request on capability, budget, or policy grounds, no SSE stream is opened and you get the same HTTP status and body a non-streaming request would return.

Once the stream is open the status has committed as 200, so a later failure arrives as an in-stream frame: response.error on the native API, a response.failed event on the OpenAI Responses surface, and an Anthropic-shaped error event on the Anthropic surface. See Streaming for each surface’s exact contract.

Degraded requests: warnings

Not every problem is an error. When Gateway serves a request but changes it on the way, a dropped tool, a clamped reasoning level, a stripped cache marker, the response carries a warnings array instead of failing. See Warnings for the code list and where warnings arrive on each surface.

Next steps