Develop / Reference

Error codes

How the gateway's error responses are structured, which type belongs to which status, how Retry-After works and which error codes it sends with which fix.

Every error response contains code, type and message

The gateway answers every error itself, including a provider’s. The body contains an error object under error. Its structure follows the format of the endpoint you called:

  • The OpenAI endpoints (/v1/chat/completions, /v1/responses, /v1/embeddings, /v1/rerank, /v1/shield/*, audio, images and the others) answer in the format of the OpenAI API, with the additional field param, which is always null.
  • /v1/messages and /v1/skills answer in the format of the Anthropic API, with "type": "error" at the top level and the request ID in request_id. The path determines the format. Only on /v1/files does the authentication header decide: with x-api-key, the endpoint answers in the Anthropic format, with Authorization: Bearer or api-key in the OpenAI format. All other endpoints answer in the OpenAI format, even if you send x-api-key.

In both formats, code identifies the error, type the error class and message holds the text in English.

FieldContent
codestable Noirdoc error code, for example key_budget_exhausted
typeerror class, derived from the status code, see The type follows the status code
messagedescription in English, often with details about the request

Check error.code in your code, not message. The text of message can change; the codes stay stable. The table All error codes gives the meaning and fix for every code.

For every error with a status code of 500 or higher, message ends with (request id <id>). The same ID is in the response headers x-request-id and request-id. Give it to support if an error persists.

The first example shows the response of an OpenAI endpoint, the second that of /v1/messages and /v1/skills.

JSON
{
  "error": {
    "type": "insufficient_quota",
    "code": "key_budget_exhausted",
    "message": "This API key has reached its spending limit. …",
    "param": null
  }
}
JSON
{
  "type": "error",
  "error": {
    "type": "billing_error",
    "code": "key_budget_exhausted",
    "message": "This API key has reached its spending limit. …"
  },
  "request_id": "4f1c…"
}

The type follows the status code

The type results from the status code of the response. The former fixed value proxy_error no longer applies.

Statustype on OpenAI endpointstype on /v1/messages and /v1/skills
400, 405, 409, 422invalid_request_errorinvalid_request_error
401authentication_errorauthentication_error
402insufficient_quotabilling_error
403permission_errorpermission_error
404not_found_errornot_found_error
413invalid_request_errorrequest_too_large
429rate_limit_errorrate_limit_error
500, 502server_errorapi_error
503server_erroroverloaded_error
504server_errortimeout_error
529not assignedoverloaded_error

The gateway also reports provider errors itself

If a provider answers with an error, the gateway creates its own error object, so your application always receives the same format. Which code results depends on the provider’s response and on the route. On routes with a provider managed by Noirdoc:

Provider’s responseGateway’s response
Capacity problem or the provider’s credit is exhausted (status code 429 or 402)429 resource_exhausted with the Retry-After header
Provider overloaded (status code 503 or 529)provider_overloaded with the Retry-After header, status 503 on OpenAI endpoints and 529 on /v1/messages and /v1/skills
The request itself is faulty (for example 400, 404, 422)provider_rejected_request with the provider’s status code and its message in shortened and cleaned-up form, at most 500 characters
Access denied (401, 403) or a provider error (5xx except 503 and 529)502 provider_error with a fixed text

The gateway logs the provider’s status, error type and error code; for 4xx request errors, it logs no message.

On routes with your own provider key (BYOK), the key, credit and quota at the provider belong to you. There, the gateway reports the provider’s status codes 401, 402, 403 and 429 as provider_rejected_request with the provider’s status code and message. For 429, it also sets Retry-After to the provider’s value if it lies between 1 and 60 seconds, otherwise to 5 seconds. If the provider reports 503 or 529, the gateway answers with provider_overloaded on these routes as well.

For a capacity problem or an overload, the gateway first tries up to three providers of the model (failover). Only if the last provider fails as well do you receive resource_exhausted or provider_overloaded. The text of message is always “The requested resource is temporarily at capacity. Retry after the number of seconds in the Retry-After header.” for resource_exhausted and always “The provider is temporarily overloaded. Retry after the number of seconds in the Retry-After header.” for provider_overloaded. Limits states how many providers the gateway tries at most.

If a managed provider answers with 429, the gateway skips it for the seconds from its Retry-After, limited to 1 to 60 seconds (10 seconds without a usable header, 60 seconds when the quota is exhausted), and tries the next provider. Providers & routing describes the limits Noirdoc sets per provider and the wait for a free provider.

Other status codes between 400 and 499 are the provider’s answer to the request itself. The gateway reports them immediately, without asking another provider, and keeps the provider’s message so you can correct the request. If the provider returns no JSON body, the message reads “The provider rejected the request.”

The X-Noirdoc-Provider header names the provider that answered last. Your response contains the headers the gateway sets itself: Content-Type, X-Noirdoc-Provider, X-Noirdoc-Shield, X-Noirdoc-Masked, X-Request-ID, Request-ID, Retry-After and, for audio and file downloads, Content-Disposition. Other provider headers, such as x-ratelimit-*, do not reach your application.

HTTP
HTTP/1.1 429 Too Many Requests
content-type: application/json
retry-after: 5
x-noirdoc-provider: <provider-slug>
x-request-id: 4f1c…

{
  "error": {
    "type": "rate_limit_error",
    "code": "resource_exhausted",
    "message": "The requested resource is temporarily …",
    "param": null
  }
}

Retry-After states the wait time in seconds

The gateway sets the Retry-After header to a whole number of seconds for these errors:

StatusCodeWait time
429starter_rate_limit_exceededThe seconds until the end of the current minute (1 to 60 seconds) or of the current UTC day
429resource_exhaustedThe provider’s value if it lies between 1 and 60 seconds, otherwise 5 seconds
503, 529provider_overloadedThe provider’s value if it lies between 1 and 60 seconds, otherwise 5 seconds
503capacity_exhaustedThe seconds until a provider is expected to be free again, at most 60; 5 seconds if this is not known
503shield_unavailable, service_overloaded, forwarding_pool_exhausted, ownership_check_unavailable, provider_auth_unavailable5 seconds
503masking_unavailable (legacy masking until 30.11.2026)10 seconds
504provider_timeout10 seconds

An error in the stream carries this wait time as retry_after in the error object instead of in the header, because the header is no longer possible at that point. This also applies to gateway_restarting with 5 seconds.

The OpenAI and Anthropic SDKs retry requests with the status codes 408, 409, 429 and 5xx on their own, unless you set max_retries to 0. They wait for the time from Retry-After if the header is present and states 60 seconds or less; otherwise they increase the wait exponentially. With your own HTTP library, wait for the stated time before you send the same request again.

If a stream breaks off, it ends with an error event

If a stream breaks off after the gateway has started the response, the gateway can no longer change the status code. It therefore ends the stream with an error in the format of the endpoint:

  • For /v1/chat/completions, it sends a line data: {"error": {"type": "...", "code": "stream_interrupted", "message": "...", "param": null}} without a chat.completion.chunk envelope and without finish_reason, followed by data: [DONE]. The OpenAI SDKs raise an APIError on it.
  • For /v1/responses, it sends an error event followed by data: [DONE]. The OpenAI Python SDK raises no exception for this event, because its content is flat like OpenAI’s error event. It yields an event with type: "error" that your loop has to check.
  • For /v1/messages, it sends an error event followed by event: message_stop.

The code in the error object is stream_interrupted. The same format applies if the request fails after the gateway has sent status code 200 following a 15-second wait. The error object then carries the code of the corresponding HTTP error and, where needed, retry_after in seconds.

During this wait, the gateway sends : ping comment lines, which SSE parsers ignore. More on this under Streaming.

Handling errors in code

The example reads the code and reacts to individual errors. For starter_rate_limit_exceeded, resource_exhausted, provider_overloaded, capacity_exhausted, shield_unavailable, service_overloaded, forwarding_pool_exhausted and provider_timeout, it states the wait time from Retry-After after which you send the request again. Errors with the status codes 500 and 502 are usually temporary. Send such requests again with a growing wait time. For 400, 401, 402, 403 (such as shield_violation, configurable under Models → Shield) and 404, a retry without changing the request changes nothing.

Python
import os
import httpx

API_KEY = os.environ["NOIRDOC_API_KEY"]

response = httpx.post(
    "https://api.noirdoc.de/v1/chat/completions",
    headers={"Authorization": f"Bearer {API_KEY}"},
    json={
        "model": "qwen3.8-27b",
        "messages": [{"role": "user", "content": "Hello"}],
    },
    # The gateway waits up to 120 s per provider,
    # with failover for up to three
    timeout=400,
)

if response.status_code >= 400:
    try:
        error = response.json()["error"]
    except (ValueError, KeyError, TypeError):
        text = response.text[:200]
        error = {"code": "unknown", "message": text}
    code = error["code"]
    if code == "key_budget_exhausted":
        print("The key's budget is used up.")
    elif code == "shield_violation":
        print(f"Shield blocked the request: {error['message']}")
    elif code in (
        "starter_rate_limit_exceeded",
        "resource_exhausted",
        "provider_overloaded",
        "capacity_exhausted",
        "shield_unavailable",
        "service_overloaded",
        "forwarding_pool_exhausted",
        "provider_timeout",
    ):
        wait = int(response.headers.get("retry-after", 5))
        print(f"At capacity, send again after {wait} s.")
    elif code == "provider_rejected_request":
        provider = response.headers.get("x-noirdoc-provider")
        print(f"{provider} rejected: {error['message']}")
    else:
        print(f"Error {code}: {error['message']}")
TypeScript
const url = "https://api.noirdoc.de/v1/chat/completions";
const res = await fetch(url, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.NOIRDOC_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "qwen3.8-27b",
    messages: [{ role: "user", content: "Hello" }],
  }),
});

if (!res.ok) {
  const body = await res.json().catch(() => null);
  const error = body?.error ?? {
    code: "unknown",
    message: res.statusText,
  };
  switch (error.code) {
    case "key_budget_exhausted":
      console.log("The key's budget is used up.");
      break;
    case "shield_violation":
      console.log(`Shield blocked: ${error.message}`);
      break;
    case "starter_rate_limit_exceeded":
    case "resource_exhausted":
    case "provider_overloaded":
    case "capacity_exhausted":
    case "shield_unavailable":
    case "service_overloaded":
    case "forwarding_pool_exhausted":
    case "provider_timeout": {
      const wait = Number(res.headers.get("retry-after") ?? 5);
      console.log(`Send again after ${wait} s.`);
      break;
    }
    case "provider_rejected_request": {
      const provider = res.headers.get("x-noirdoc-provider");
      console.log(`${provider} rejected: ${error.message}`);
      break;
    }
    default:
      console.log(`Error ${error.code}: ${error.message}`);
  }
}

All error codes

The table groups the codes by status code. Each row has its own anchor, for example key_budget_exhausted.

Code Meaning Fix
400Bad request
invalid_request_path The path contains a dot segment (. or ..), a %, a backslash or a control character. Send the path without dot segments and without encoded characters, for example /v1/chat/completions.
model_required The request names no model (model in the body, or in the form field for /v1/audio/transcriptions). Pass a model ID from GET /v1/models.
wrong_endpoint_for_model The model belongs to a different endpoint family or API format than the endpoint called. Call the model through the matching endpoint, for example an embedding model through /v1/embeddings.
streaming_not_supported_for_endpoint The request asks for streaming, but the endpoint does not support it. Remove stream from the request.
invalid_request_body The body is not a JSON object or not encoded in UTF-8. Send the body as a JSON object in UTF-8 with Content-Type: application/json and check the field named in message.
invalid_request_error A parameter on /v1/shield/inspect or /v1/shield/policy is invalid (such as an empty input or one over 256 KB, more than 64 entries, an unknown rule or an invalid custom pattern), or the JSON body is nested too deeply for Shield extraction. Check message and adjust input (1 to 64 non-empty strings, at most 256 KB in total), rules, mode or custom_patterns according to the /v1/shield reference.
provider_rejected_request The provider itself rejected the request, for example because of an invalid parameter or a context that is too long. The response carries the provider's status code (400, 404, 409, 413, 422 or another 4xx status code except 401, 402, 403 and 429), and message contains the provider's message, shortened and sanitised, at most 500 characters. On routes with your own provider key (BYOK) the gateway also reports the provider's status codes 401, 402, 403 and 429 this way, because the key, credit and quota belong to the customer; with 429 it adds Retry-After. Correct the request based on the message. Repeating it unchanged fails again. X-Noirdoc-Provider names the provider.
invalid_image_request prompt, n or size is outside the gateway's limits; message names the parameter. Correct the named parameter. Split large image requests into several requests.
invalid_rerank_request query is not a non-empty string, documents is not a list of 1 to 1,000 strings or top_n is not an integer of at least 1; message names the field. Send query and each document as plain text, at most 1,000 documents per request, and top_n as an integer of at least 1.
invalid_tts_request input or voice is missing or empty, or input is too long. Send input and voice as non-empty strings and shorten input to at most 4,096 characters.
invalid_multipart_body The body is not valid multipart/form-data, or model, stream or response_format appears more than once. Send the audio file as a multipart form with each of these fields at most once.
invalid_request_tags The X-Noirdoc-Tags header or the tag name in the path under /v1/tags is empty, contains more than 5 tags or does not match the format ^[a-zA-Z0-9][a-zA-Z0-9_.:-]{0,63}$. Send 1 to 5 comma-separated tag names of 1 to 64 characters each (a-z, A-Z, 0-9 and _ . : -, starting with a letter or digit).
401Not authenticated
invalid_api_key The key is missing, invalid or deactivated, or the organisation is not active. Send a valid key starting with px- in the Authorization: Bearer, x-api-key or api-key (Azure style) header. Check the key under Models → API keys.
402Credit or budget
insufficient_credit The organisation's credit is used up or lower than the estimated maximum cost of the request (including Noirdoc Shield, also on BYOK routes when Shield is active). Top up credit under Billing → Top up, or lower max_tokens or shorten the input.
key_budget_exhausted This key's budget is used up for the current period or does not cover the estimated cost of the request. Raise the spending limit under Models → API keys, lower max_tokens or wait for the next reset.
tag_budget_exhausted The budget of a tag named in X-Noirdoc-Tags is used up for the current period or does not cover the estimated cost of the request; message names the tag. Raise the tag's spending limit under Models → Tags or through /v1/tags, lower max_tokens or wait for the next reset.
403Not allowed
endpoint_not_available_on_platform The call would read data from the shared account of a provider managed by Noirdoc and is blocked there. Connect your own provider key (BYOK) for this endpoint under Models → Providers.
stored_responses_disabled The request would store input and response at the managed provider (store, previous_response_id or a sub-route for stored responses), and your organisation has not turned on storage at the provider. Send the history with every request, ask an admin to turn on “Allow Responses API storage at provider” under Models → Shield, or use your own provider key (BYOK).
reference_not_available_on_platform The body refers to objects at the provider (such as conversation, prompt.id or vector_store_ids) whose ownership the gateway cannot check for managed providers. Remove the fields named in message or use your own provider key (BYOK).
model_not_allowed_for_key The model is not one of this key's allowed models. Choose a model from GET /v1/models or extend the allowed models under Models → API keys.
provider_not_allowed_for_tenant The organisation counts as bound by professional secrecy (§ 203 StGB); this excludes every provider that offers this model. Choose a model from GET /v1/models. The list contains only models with permitted providers.
provider_not_allowed_for_key The key's restrictions (providers, data residency, CLOUD Act, § 203) exclude every provider of this model. Choose a model from GET /v1/models or relax the restrictions under Models → API keys.
starter_model_not_allowed The organisation is still using only its starter credit, and the model or its managed provider is not included in starter credit. Choose a starter-eligible model from GET /v1/models, connect your own provider key under Models → BYOK, or top up credit once under Billing → Top up to unlock all managed models immediately.
shield_violation Noirdoc Shield blocked the request before forwarding to the provider because an active protection filter configured with block matched; message names the triggered rule (secrets, pii, ner, injection or custom). Remove the triggering content from the request, or change the rule under Models → Shield or via /v1/shield/policy to redact or off (off only for injection).
shield_policy_enforced The organisation's Shield policy is enforced, and the request to /v1/shield/inspect tries to weaken an active rule or omit custom patterns via policy. Omit policy or pass only equally strict or stricter rules (redact to block, or additional custom_patterns).
masking_not_supported_for_endpoint The endpoint supports neither Noirdoc Shield nor legacy masking, yet the policy is enforced or the request sends X-Noirdoc-Mask: on (and on /v1/images/generations also X-Noirdoc-Shield: on). During the legacy masking transition until 30.11.2026, this also affects /v1/embeddings and /v1/rerank on pre-existing organisations that have not switched to Shield yet. Leave out the header. With enforced, an admin can change the default setting under Models → Shield; for /v1/embeddings and /v1/rerank, switching to Noirdoc Shield enables inspection.
file_content_not_allowed The request contains files, images or audio, and the organisation does not allow file content. Send the request without files, or ask an admin to turn on “Allow file and image attachments in requests” under Models → Shield in Advanced Settings.
file_pii_blocked A file contains personal data, and the organisation's legacy file analysis (transition until 30.11.2026) is set to block or to detect_only under enforced. Remove the personal data from the file, or switch to Noirdoc Shield under Models → Shield.
model_not_billable The model has no complete price on record, so it cannot be used with credit. Choose another model or contact support.
request_tags_disabled The request sends X-Noirdoc-Tags or calls /v1/tags, but request tags (Preview) are not enabled for this organisation. Remove the X-Noirdoc-Tags header or have request tags enabled for your organisation.
tag_not_found The named tag does not exist. On requests with X-Noirdoc-Tags, automatic tag creation is turned off (status code 403); on /v1/tags/{name}, the gateway answers with status code 404. Create the tag under Models → Tags or with POST /v1/tags, or turn on automatic creation in the default tag template.
tag_disabled A tag named in X-Noirdoc-Tags is deactivated. Activate the tag under Models → Tags or through /v1/tags, or remove it from X-Noirdoc-Tags.
tag_limit_exceeded The organisation has reached the maximum of 1,000 request tags. Delete unused tags without spend history under Models → Tags or with DELETE /v1/tags/{name}, or reuse existing tags.
insufficient_key_permissions The API key lacks permission for /v1/tags (can_manage_tags) or /v1/shield/policy (can_manage_shield), a key pinned to shield_mode: on tries to weaken the Shield policy or a tag's shield_mode, or the tag requests broader models, providers or compliance rules than the calling key itself holds. Turn on the corresponding management permission under Models → API keys (“Allow tag management (/v1/tags)” or “Manage Shield policy via API”) and modify policies only within that key's own constraints.
model_not_allowed_for_tag The model is not one of the allowed models of a tag named in X-Noirdoc-Tags. Choose a model from GET /v1/models (with the same X-Noirdoc-Tags header) or extend the tag's allowed models under Models → Tags.
provider_not_allowed_for_tag The restrictions of a tag named in X-Noirdoc-Tags (providers, data residency, CLOUD Act, § 203) exclude every provider of this model. Choose a model from GET /v1/models (with the same X-Noirdoc-Tags header) or relax the tag's restrictions under Models → Tags.
404Not found
unsupported_endpoint The gateway does not know this path. Use an endpoint from the reference and check the spelling and the /v1/ prefix.
object_not_found The object (file, skill or stored response) does not exist or does not belong to your organisation. Check the ID. Use only IDs that your organisation created through the gateway.
model_not_available The model ID is not available to the organisation. Check the model ID with GET /v1/models.
http_error A request fails with a general HTTP error for which the gateway has no code of its own. The status code follows the error: 404 for an unknown path, 405 for a wrong method and 503 with Retry-After: 5 when an endpoint is not available in standalone mode. Read message and check the method and path of the request.
405Method not allowed
method_not_allowed The endpoint accepts only POST. Send the request with POST.
409Conflict
tag_already_exists A tag with this name already exists in the organisation. Choose a different tag name or update the existing tag with PUT /v1/tags/{name} or PATCH /v1/tags/{name}.
tag_has_spend_history Spend has already been recorded for this tag, so it cannot be permanently deleted. Leave the tag in the “Inactive” state so that counters and billing history remain intact.
413Request too large
request_too_large The body exceeds the endpoint's size limit. Shrink or split the body, for example the audio file or embedded files. The values are listed under Limits.
shield_input_too_large The text to inspect in this request exceeds the Shield service limit of 4 MiB of encoded text in a single call. Split large inputs or inline text files across several smaller requests.
masking_input_too_large A single text segment in a legacy-masked request (transition until 30.11.2026) exceeds the detector's character limit. Split the text into smaller parts or switch to Noirdoc Shield under Models → Shield.
422Unprocessable
shield_uninspectable_content The Shield policy is enforced, and the request carries content that Shield cannot inspect as text (binary_document such as PDF or Office, media_not_inspectable such as images, audio or video, file_reference by ID or URL, file_too_large at 4 MiB or above, file_not_decodable or unrecognised_content). The gateway did not forward the request. Extract the text beforehand and send it as message text or an inline UTF-8 text file under 4 MiB, or change the default setting from enforced to default_on under Models → Shield.
shield_policy_invalid The submitted Shield policy is inconsistent, such as enforced with all five protection filters set to off, or mixing rules/custom_patterns with flat rule keys. Enable at least one protection filter when using enforced, and pass rule actions together inside the rules object.
shield_config_invalid The organisation's stored Shield configuration is invalid (for example enforced without any active protection filter, or a pattern that fails compilation); the gateway did not forward the request. Review and re-save the protection filters and custom blocklist under Models → Shield or via /v1/shield/policy.
file_unprocessable A file could not be processed in legacy file analysis (transition until 30.11.2026): it is too large, unreadable or in a format without analysis. The gateway did not forward the request. Save the file again or in another format (such as PDF, DOCX or XLSX), make it smaller, or extract the text beforehand for Noirdoc Shield.
429Rate limit or provider at capacity
starter_rate_limit_exceeded The organisation is still using only its starter credit and has reached the limit of 5 requests per minute or 25 requests per day (UTC) for managed providers. The response contains Retry-After with the wait in seconds. Top up credit under Billing → Top up to lift the limit immediately, or wait the seconds from Retry-After.
resource_exhausted The provider reported capacity problems or exhausted credit (status code 429 or 402), even after failover across up to three providers. The response contains Retry-After with the wait in seconds. Wait the seconds from Retry-After and send the request again. The OpenAI and Anthropic SDKs do this on their own.
500Internal error
internal_error An unexpected error occurred in the gateway. Send the request again. If the error persists, give support the request ID from message or x-request-id.
detection_error Detecting personal data in legacy masking (transition until 30.11.2026) failed; the gateway did not forward the request. Send the request again. If the error persists, contact support or switch to Noirdoc Shield under Models → Shield.
file_analysis_error Reserved for file analysis errors. The gateway does not currently send this code. Send the request again.
502Provider error
provider_not_configured The organisation has no suitable provider set up for this request. Connect a provider for this API format under Models → Providers.
provider_misconfigured The configuration of the selected provider is invalid, for example a base URL that is not allowed. Check the provider's base URL and settings under Models → Providers. If a provider managed by Noirdoc is affected, contact support.
provider_unreachable The gateway could not connect to the provider, or the connection dropped. Send the request again after a short wait.
provider_error The provider answered with an error (status code 5xx except 503 and 529, or 401 and 403 on routes with a provider managed by Noirdoc) that the request did not cause. The gateway replaces the provider's message with a fixed text. On routes with your own provider key it reports 401 and 403 as provider_rejected_request. Send the request again. If the error persists, give support the request ID from message or x-request-id.
stream_interrupted The provider's stream broke off or reported an error after the response had started. The error is in the stream itself, because status code 200 has already been sent by then. stream_interrupted carries no retry_after; only errors in the stream that correspond to an HTTP error with a wait carry it. Discard the incomplete response and send the request again.
503Temporarily unavailable
capacity_exhausted All providers of the model were at their capacity limit or paused after a 429, even after a wait of up to 10 seconds. The response contains Retry-After with the seconds until a provider is expected to be free again, at most 60, or 5 seconds if that is not known. Wait the seconds from Retry-After and send the request again. The OpenAI and Anthropic SDKs do this on their own.
provider_overloaded The provider reported overload (status code 503 or 529), even after failover across up to three providers. The status code is 503 on OpenAI endpoints and 529 on /v1/messages and /v1/skills. The response contains Retry-After with the provider's value between 1 and 60 seconds, otherwise 5 seconds. Wait the seconds from Retry-After and send the request again. The OpenAI and Anthropic SDKs do this on their own.
service_overloaded The gateway is temporarily at capacity. The response contains Retry-After with 5 seconds. Wait the seconds from Retry-After and send the request again.
forwarding_pool_exhausted All of the gateway's connections to the providers are in use. This is a limit of the gateway, not of a provider. The response contains Retry-After with 5 seconds. Wait the seconds from Retry-After and send the request again. The OpenAI and Anthropic SDKs do this on their own.
provider_auth_unavailable The gateway's credentials for the provider are currently unavailable. The response contains Retry-After with 5 seconds. Send the request again later.
ownership_check_unavailable The gateway could not check just now whether the object belongs to your organisation and rejected the request. The response contains Retry-After with 5 seconds. Send the request again.
shield_unavailable The Noirdoc Shield inspection service is temporarily unreachable; the gateway never forwards a request that requires inspection uninspected (fail-closed). The response contains Retry-After with 5 seconds. Wait the seconds from Retry-After and send the request again. The OpenAI and Anthropic SDKs do this on their own.
masking_unavailable The legacy masking detector (transition until 30.11.2026) is temporarily unreachable; the gateway did not forward the request. The response contains Retry-After with 10 seconds. Wait the seconds from Retry-After and send the request again.
gateway_restarting The gateway was restarted (deployment) while the stream was still waiting for the provider's response. The error is in the running stream, because status code 200 has already been sent by then. The error object contains retry_after with 5 seconds. Wait the seconds from retry_after and send the request again.
504Timeout
provider_timeout The provider did not answer within the gateway's timeout. The response contains Retry-After with 10 seconds. Wait the seconds from Retry-After and send the request again.