Docs/ Reference

Errors and recovery reference

Understand errors in client responses, route inspection, and request logs, and decide whether to retry, recover, or change configuration.

Three distinct error namespaces §

One failure can expose three kinds of code, each with a different purpose:

Field Where it appears Purpose
code Client HTTP response Tells the caller why this request failed
error_code Request log and attempt chain Normalizes upstream failures for filtering and diagnosis
reason_code Route checking Explains why an AccessKey, Group, or credential cannot be a candidate
Do not substitute one code namespace for another

Route inspection may show no_available_group, while the real request may return no_available_candidate and the request log may record upstream_client_error for the last upstream attempt. Automation must read the field defined by the interface it is calling.

Do not parse message

Management API message values are localized, and upstream messages may change. Programs should use code and structured data for decisions; message and error_summary are for human readers only.

Management API errors §

Management API error codes use uppercase snake case. See Management API for the response envelope, authentication, and main resources.

Common, authentication, and resource errors

Error code HTTP Meaning How to handle
BAD_REQUEST400 Request parameters or path are invalid Correct the request and try again
INVALID_JSON400 The JSON format, fields, or body shape is invalid Correct the JSON to match the endpoint contract
VALIDATION_FAILED400 The request parsed but failed business validation Inspect field-location details in data
REQUEST_TOO_LARGE413 The management request body exceeds the size limit Reduce the body or split the operation
UNAUTHORIZED401 The management credential is invalid Check the AUTH_KEY or AccessKey
FORBIDDEN403 The current identity cannot perform this operation Use AUTH_KEY or reduce the operation scope
AUTH_LOCKED429 The direct peer was temporarily locked after repeated authentication failures Wait for Retry-After and stop retrying the wrong key
NOT_FOUND404 The target resource does not exist Refresh the resource list and verify the ID
ROUTE_NOT_FOUND404 The requested management route does not exist or has been retired Check the path against the current version's route contract
METHOD_NOT_ALLOWED405 The management route exists, but the HTTP method is unsupported Use a method declared by that route
DUPLICATE_RESOURCE409 The unique resource already exists Reuse the existing resource or change the unique field
BAD_GATEWAY502 An upstream request required by the management operation failed Inspect data and upstream status before retrying
DATABASE_ERROR500 The database operation failed Check service logs and database availability
INTERNAL_SERVER_ERROR500 An unclassified internal error occurred Diagnose with service logs; do not blindly replay writes

Idempotency, concurrency, and runtime recovery

Error code HTTP Meaning How to handle
IDEMPOTENCY_KEY_REQUIRED428 This write operation requires an Idempotency-Key Generate a canonical UUID v4 and send it with the request
INVALID_IDEMPOTENCY_KEY400 The Idempotency-Key is not a canonical lowercase UUID v4 Replace it with a canonical UUID v4
IDEMPOTENCY_KEY_REUSED409 The same idempotency key was used for a different request Generate a new key for the new logical operation
IDEMPOTENCY_RESULT_EXPIRED410 The idempotent result expired, but the operation identity remains known Use data to verify the completed resource instead of creating it again
CONTROL_OPERATION_INCOMPLETE503 The database commit succeeded, but runtime recovery is incomplete Keep the same idempotency key and wait for automatic reconciliation
CONTROL_RECOVERY_PENDING503 An earlier committed operation is still recovering Wait for data.retry_after_ms before retrying
SETTINGS_PRECONDITION_REQUIRED428 The settings update is missing If-Match Read the settings and ETag, then update with If-Match
SETTINGS_VERSION_CONFLICT412 The settings changed after they were read Merge again using the current settings in data

Groups, models, and subscription credentials

Error code HTTP Meaning How to handle
GROUP_IN_USE409 The Group is still referenced by AccessKeys Remove the references listed in data first
INVALID_CREDENTIAL_STATE409 The credential cannot be restored from its current state Refresh credential state and choose an allowed operation
CHANNEL_TARGET_CONFLICT409 Another Group already uses the same channel target Reuse the existing Group or explicitly confirm the duplicate target
MODEL_NAME_CONFLICT409 Client-visible model names conflict within the Group Correct model names or aliases using data.conflicts
NO_ACTIVE_CREDENTIAL409 The Group has no credential available for the operation Add, enable, or reauthorize a credential
MODEL_PRICE_UNPRICED_CONFIRMATION_REQUIRED409 Marking the model as unpriced requires explicit confirmation Confirm and submit again
MODEL_PRICE_REFERENCED409 The model price is still referenced by Groups Remove references before deleting the price
MODEL_PRICE_AUTOMATIC_DELETE_FORBIDDEN409 Automatically synchronized model prices cannot be deleted manually Change the sync source or wait for a later sync
OAUTH_FILE_INVALID400 The OAuth JSON is unrecognized or contains invalid fields Export again and import the complete file
OAUTH_FILE_TOO_LARGE413 The OAuth file exceeds the size limit Keep only the required credential content
AUTHORIZATION_UNAVAILABLE503 Browser authorization, device-code authorization, or subscription credential refresh is temporarily unavailable Check channel capabilities, networking, and service logs
AUTHORIZATION_STATE_INVALID400 The authorization callback state is invalid or mismatched Start a new authorization
AUTHORIZATION_EXCHANGE_FAILED502 Exchanging the authorization code for a credential failed Check upstream status and authorize again
STAGED_CREDENTIAL_NOT_READY409 The staged credential has not completed authorization Complete authorization before connecting it
STAGED_CREDENTIAL_EXPIRED410 The staged credential expired Import or authorize again
STAGED_CREDENTIAL_CONSUMED409 The staged credential was already consumed Refresh the list and do not connect it again
STAGED_CREDENTIAL_MISMATCH409 The staged credential does not match the target Group Select the matching channel and Group
DUPLICATE_CREDENTIAL_IDENTITY409 The same subscription account already exists in the Group Use the existing account or connect it to another Group
CREDENTIAL_REAUTHORIZATION_REQUIRED409 The credential requires reauthorization Complete OAuth authorization again
CREDENTIAL_AUTH_OUTCOME_UNKNOWN409 The authorization outcome cannot be confirmed Refresh state before starting another authorization
CREDENTIAL_REFRESH_TEMPORARILY_UNAVAILABLE503 The credential cannot be refreshed temporarily Retry later or use another credential
CREDENTIAL_VERSION_CONFLICT409 The credential changed during the operation Refresh the credential and repeat the operation
RESET_CREDIT_UNAVAILABLE409 No reset credit is currently available Wait for the upstream to provide another reset opportunity
RESET_CREDIT_REJECTED502 The upstream rejected the quota reset Inspect account status and contact the upstream
RESET_CREDIT_OUTCOME_UNKNOWN503 The quota-reset outcome cannot be confirmed Retry with the same Idempotency-Key
data is part of the error contract

data is returned only when callers need it to make a decision. Common contents include conflicting resources, field locations, current settings and ETag, operation IDs, failed stages, retry timing, and quota details. Errors without a declared shape usually omit data.

Structured data for management errors

The table lists only management errors with stable structured data. The same error code may still omit data in another context.

Error code data fields Returned when
VALIDATION_FAILEDentry, field, reason_code Some credential field validations fail
AUTH_LOCKEDretry_after_seconds Authentication is locked; a Retry-After header is also returned
BAD_GATEWAYtrigger, checked_at_ms, successful_fetch_at_ms, not_modified, skipped, error_code A manual Models.dev sync fails
IDEMPOTENCY_KEY_REUSEDoperation_id, operation_kind The idempotency key belongs to another request
IDEMPOTENCY_RESULT_EXPIREDoperation_id, operation_kind, resource_identity, completed_at_ms The idempotent result has been compacted
CONTROL_OPERATION_INCOMPLETEoperation_id, operation_kind, last_completed_stage, failed_stage, can_reconcile Runtime recovery remains incomplete after the database commit
CONTROL_RECOVERY_PENDINGoperation_id, operation_kind, failed_stage, retry_after_ms An earlier committed operation blocks the current write
SETTINGS_VERSION_CONFLICTsettings, settings_etag The If-Match value is stale
GROUP_IN_USEaccess_keys[] { id, name } Deleting a Group still referenced by AccessKeys
CHANNEL_TARGET_CONFLICTgroups[] { id, name } Creating a duplicate channel target without confirmation
MODEL_NAME_CONFLICTconflicts[] { client_model, indexes } Group model names or aliases conflict
MODEL_PRICE_UNPRICED_CONFIRMATION_REQUIREDid Setting every price to null without confirmation
MODEL_PRICE_REFERENCEDid, reference_count, reference_group_count Deleting a price still referenced by Groups
MODEL_PRICE_AUTOMATIC_DELETE_FORBIDDENid Deleting an automatically synchronized price

Data-plane errors §

Data-plane errors generated by GPT-Load use lowercase snake case and the base shape { "code": "...", "message": "..." }. Cost-limit errors also return structured error and data.

Error code HTTP Meaning How to handle
invalid_access_key401 The AccessKey is missing, disabled, expired, or not allowed from this source Check the AccessKey used by the client; these failures are not written to request logs
protocol_endpoint_not_found404 The path is not an enabled data-plane endpoint Verify the base URL, protocol, and path
method_not_allowed405 The endpoint exists, but the HTTP method is unsupported Use a method declared by the endpoint
invalid_protocol_request400 The request body or protocol fields cannot be parsed Correct the request for the client protocol
model_required_by_filter400 The AccessKey filters models, but the request has no model Specify a model or remove the model filter
no_available_candidate503 No Group or credential is currently routable Use route inspection to find the specific reason_code
upstream_connect_failed502 No available upstream could be reached Check the network, proxy, and upstream address before retrying
upstream_timeout504 The upstream request timed out Inspect dispatch and commit state in the request log; do not blindly replay non-idempotent requests
upstream_protocol_error502 The upstream response could not be processed safely Check the upstream response format, Content-Encoding, and service logs
protocol_conversion_unsupported422 No route can execute the request natively or convert it safely Change the protocol, operation, or channel
request_too_large413 The data-plane request body exceeds the size limit Reduce the request body
unsupported_content_encoding415 The request uses an unsupported Content-Encoding Use identity, gzip, br, deflate, or zstd
invalid_content_encoding400 The compressed request body cannot be decoded Encode the body again and verify the request headers
not_acceptable406 The client does not accept an identity-encoded response Allow identity-encoded responses
model_list_too_large500 The visible model list exceeds the safe response limit Reduce the models visible to the AccessKey
access_key_rate_limited429 The AccessKey exceeded its RPM limit Wait for Retry-After
access_key_cost_limit_exceeded429 The AccessKey reached an estimated-cost limit Inspect data.recoverable, next_available_at_ms, and blocking_rules
configuration_changed503 The configuration snapshot used by the request is stale Wait briefly according to Retry-After, then retry

For access_key_cost_limit_exceeded, error contains type, code, message, and optional resets_at in Unix seconds; data contains recoverable, next_available_at_ms in Unix milliseconds, and blocking_rules. Each blocking rule contains id, kind, limit_usd, and used_usd; periodic rules also include period_seconds and window_ends_at_ms.

Upstream errors may use another structure

Native routes return the upstream error body after redaction and safety checks; converted routes project it into the client protocol's error shape. OpenAI, Anthropic, and Gemini clients may therefore see different fields. Do not assume every failure contains only code and message.

Request-log errors §

Top-level error_code is the final request outcome; attempts[].error_code belongs to one upstream attempt. When a retry succeeds, the top level may have no error while earlier attempts retain their error codes.

This table lists only additional normalized request-log codes. Codes shared with fixed data-plane errors are defined in the previous section and are not repeated.

Error code Meaning How to handle
upstream_rate_limited The upstream rate-limited this attempt Inspect Retry-After, cooldown, and later attempts
upstream_model_unavailable The upstream model or candidate is unavailable Check model configuration and later candidates
upstream_invalid_key The upstream rejected the channel credential Update the credential and check accumulated failures or blacklisting
upstream_authentication_required The subscription credential needs refresh or reauthorization Inspect the retry decision and reauthorize
upstream_host_error The upstream returned a server error Check whether the Group was skipped and whether another attempt ran
upstream_client_error The upstream considers the request itself invalid Inspect the error summary and request parameters; switching credentials is usually inappropriate
upstream_error An upstream failure that could not be classified further Use the status, summary, and matched rule together
upstream_sse_error The upstream reported an error in an SSE event Check whether the stream was committed; it cannot be retried after output starts
upstream_stream_terminated The upstream stream ended before completion Check the network and stream idle timeout
upstream_stream_idle_timeout The upstream stream produced no data for too long Adjust the stream idle timeout or inspect the upstream
upstream_response_incomplete The upstream explicitly reported an incomplete response Inspect the error summary and upstream request ID
downstream_write_failed Writing the response to the client failed Check client disconnects, the reverse proxy, and the network
client_canceled The client canceled the request Usually no action is required
server_shutdown The request was canceled during server shutdown After service recovery, the caller decides whether to retry
internal_error The request ended without a classifiable normal result Inspect service logs for the same Request ID
credential_decrypt_failed The candidate credential could not be decrypted Restore the matching ENCRYPTION_KEY or enter the credential again
credential_normalization_failed The candidate credential could not be normalized for execution Enter a valid credential again
credential_proxy_prepare_failed The credential-level proxy could not be initialized Correct the proxy configuration for this credential
group_proxy_prepare_failed The Group-level proxy could not be initialized Correct the Group proxy configuration
server_is_overloaded The upstream explicitly reported overload Inspect replay safety and later candidates
rate_limit_exceeded The upstream explicitly reported capacity limiting Inspect cooldown and later candidates
Request logs store a safe summary

error_summary is redacted and length-bounded; raw error bodies are never written to request logs. AccessKey authentication fails before a RequestLog exists, so it only returns invalid_access_key and emits a rate-limited security event.

Request-log fields §

Request level

Field Values How to interpret it
request_idUUID v4 GPT-Load request ID used to correlate request details and service logs
statussuccess / error / incomplete / canceled Final status of the whole request
status_code 0 / HTTP status Final request status code; it can be 0 when no HTTP response was produced
error_code Normalized error code Use it for filtering and aggregation; do not infer it from error_summary
error_summary Redacted, length-bounded summary For human diagnosis; it does not guarantee verbatim upstream text
attempt_count Non-negative integer Actual number of recorded upstream or local execution attempts

Attempt fields in attempts[]

Field Values How to interpret it
sequence Integer starting at 1 Attempt order within this request
status_code 0 / HTTP status Status code for this attempt; it can be 0 when the upstream did not respond
error_code Normalized error code Failure reason for this attempt; an empty string on success
error_summary Redacted, length-bounded summary For human troubleshooting only
failure_categoryok / rate_limited / model_unavailable / invalid_key / upstream_host_error / client_error / conversion_unsupported / downstream_cancel / authentication_required / ambiguous Stable business category; a successful attempt uses ok
failure_originclient / upstream / downstream / internal / null Failure responsibility domain; legacy records may be null
failure_scoperequest / model / credential / group / null Smallest affected resource scope; null when not applicable or for legacy records
retry_directivenone / refresh_credential / next_candidate / null Retry intent selected by Judge; legacy records may be null
effectnone / cooldown_credential / record_credential_failure / skip_group / null The attempt's single runtime effect; legacy records may be null
rule_id Stable rule identifier / null Rule that produced the decision; legacy records may be null
will_retrytrue / false Whether another upstream attempt actually started afterward
dispatch_statenot_sent / maybe_sent / local / null Definitely not sent, possibly reached the upstream, completed entirely inside GPT-Load, or unknown for a legacy record
response_startedtrue / false Whether this attempt produced a response; local attempts may also be true
committedtrue / false Whether client output has started; candidates cannot be switched safely after commit
upstream_request_id Upstream request ID / null Use it with upstream support; null for local execution or when the upstream returned no ID
actionterminate / retry / cooldown_credential / fail_credential / skip_group Compatibility display field; use retry_directive and effect for precise decisions

Complete example §

One failed attempt in a request log
status_code: 400
error_code: upstream_client_error
failure_category: client_error
failure_origin: upstream
failure_scope: request
retry_directive: none
effect: none
rule_id: fallback.http_client_error
will_retry: false
response_started: true
committed: false

The upstream returned 400 and the problem affects only this request. The gateway does not switch credentials, cool down or blacklist the credential, or skip the Group. Inspect the redacted error summary and client request parameters.

Route-inspection reason codes §

Route inspection is a read-only simulation of current configuration and runtime state. It sends no upstream request, consumes no tokens, locks no credential, and writes no request log. The top-level reason explains the overall failure; Group and credential rows provide more detail.

Reason code Level Meaning How to handle
access_key_disabled AccessKey AccessKey has been deactivated Enable it on the AccessKeys page
access_key_expired AccessKey AccessKey has expired Create a new key or extend validity
protocol_filtered AccessKey This key has not selected this protocol Add a check for the corresponding protocol in the key
model_filtered AccessKey Requested model is not within the allowed range Check model limitations for the key
model_required_by_filter AccessKey The key restricts models, but the request carried no model name Name the model explicitly in the request, or drop the key's model restriction
operation_unsupported Request No channel supports this operation for the current protocol Use a Group that supports the capability
no_route_target Request No route target exists for this model or operation Confirm that at least one Group exposes the model
no_available_group Request Route targets exist, but no Group is available Inspect each Group's reason_code
native_route_required Group The request requires a native route, but this Group can only serve it through conversion Use a Group whose protocol matches the client
group_disabled Group Group is deactivated Enable this Group
group_filtered Group Group is not within the authorization scope of this key Add this Group in the key
no_credentials Group There is not a single credential in the Group. Add credentials to the Group
group_weight_zero Group A legacy configuration has a Group weight of 0 Switch to automatic weight or a manual weight from 1 to 100
no_available_credential Group Every credential in the Group is unavailable Continue with credential-level reason_code values
credential_disabled Credential Credential has been deactivated Enable it, or depend on other credentials
credential_auth_unavailable Credential Subscription account authorization has expired Reauthorize, see subscription account page
credential_blacklisted Credential Credential has been blacklisted Verify the credential, then restore it
credential_cooldown Credential Credential is in cooldown Wait for automatic recovery, or add more credentials to share the load
credential_weight_zero Credential A credential weight of 0 left over from an old configuration Switch to automatic weight or a manual weight from 1 to 100
Internal exclusion reason is not returned by current route inspection

The scheduler also defines credential_not_allowed to constrain a real request to the credential set captured when that request started. The current /api/route/inspect endpoint does not accept that request-scoped credential set, so it does not return this reason code.

After changing configuration, run route inspection again to verify current state without sending a real model request.

Retry and recovery §

  • Request error — correct the request; do not switch credentials or change credential health.
  • Rate limit — honor Retry-After; credential-scoped limits usually cause cooldown and another candidate attempt.
  • Invalid credential — record a credential failure and blacklist it after the consecutive-failure threshold.
  • Upstream host error — skip the current Group; replay is safe only for read-only operations or when the upstream proves it rejected processing.
  • Streaming response — candidates cannot be switched after client output starts, preventing duplicate or corrupted output.
  • Indeterminate management write — preserve and reuse the original Idempotency-Key and confirm operation state first.

View the complete scheduling, cooldown, and blacklisting behavior →

Errors and recovery - GPT-Load