Error Codes
Stable Qufas HTTP and streaming error shapes, codes, and recovery actions.
Documented statuses
The stable Runtime/OpenAPI contract uses HTTP 400, 401, 402, 403, 404, 429, 500, 502, 503, and 504. HTTP 409 and 422 are not part of the current public contract.
Error response format
Depend on type, param, code, HTTP status, and the response request ID. Messages are human-readable and may evolve.
1{2 "error": {3 "message": "The parameter 'n' is not supported by this gateway.",4 "type": "invalid_request_error",5 "param": "n",6 "code": "unsupported_parameter"7 }8}Documented machine-readable codes
This table covers stable public HTTP errors and the runtime SSE failures developers need to handle. It does not expose internal diagnostics, and it should not be interpreted as a promise that no additional machine-readable code can be introduced.
| HTTP | Type | Code | Meaning | Common cause | Retryable | Developer action |
|---|---|---|---|---|---|---|
| 400 | invalid_request_error | invalid_json | The body is not valid JSON. | Malformed JSON. | no | Fix JSON syntax and retry. |
| 400 | invalid_request_error | invalid_request | The request object is invalid. | Wrong top-level shape. | no | Send a JSON object matching the endpoint schema. |
| 400 | invalid_request_error | missing_required_parameter | A required field is missing. | Missing model, messages, or prompt. | no | Add the field named by error.param. |
| 400 | invalid_request_error | invalid_parameter | A supported parameter has an invalid value. | Wrong type, range, or message shape. | no | Use the documented constraint for error.param. |
| 400 | invalid_request_error | unsupported_parameter | The parameter is not in the stable Qufas contract. | An OpenAI option not supported by Qufas was sent. | no | Remove the field named by error.param. |
| 400 | invalid_request_error | invalid_model | The model cannot serve this workload. | Disabled model or wrong workload type. | no | Choose an eligible ID from GET /v1/models. |
| 400 | invalid_request_error | invalid_n | The requested image count is invalid. | n is not an integer from 1 through 4. | no | Send n between 1 and 4. |
| 400 | invalid_request_error | invalid_size | The image size is invalid or unsupported. | Wrong size format or model size. | no | Use a supported size for the selected image model. |
| 400 | invalid_request_error | invalid_cursor | The generation-list cursor is invalid or cannot be verified. | Malformed, expired, or incompatible cursor. | no | Restart pagination without the cursor. |
| 400 | invalid_request_error | invalid_response_format | The image response format value is invalid. | response_format is not url or b64_json. | no | Use the supported public value url. |
| 400 | invalid_request_error | model_pricing_not_configured | The selected model has no callable billing configuration. | Model pricing metadata is incomplete. | no | Choose another callable model or contact support. |
| 401 | authentication_error | invalid_api_key | The API key is missing, malformed, inactive, or invalid. | Bearer authentication failed. | no | Send an active qf_sk_ key from server-side code. |
| 401 | authentication_error | expired_api_key | The API key has expired. | expires_at has passed. | no | Create a replacement in the dashboard and revoke the old key. |
| 402 | insufficient_balance | insufficient_balance | The prepaid balance cannot cover execution. | Account balance is insufficient. | no | Add credits, then retry the logical operation. |
| 403 | permission_error | model_not_allowed | The key cannot use this model. | Model allowlist denied the request. | no | Use an allowed model or update the key in the dashboard. |
| 403 | permission_error | monthly_spend_limit_exceeded | The key reached its monthly spend limit. | Configured key spend policy. | no | Raise the dashboard limit or wait for reset. |
| 404 | invalid_request_error | model_not_found | The requested model is unavailable. | Unknown or non-callable model ID. | no | Refresh GET /v1/models and choose a returned ID. |
| 404 | invalid_request_error | generation_not_found | The requested Generation is not visible to this API key. | Unknown request ID or a Generation owned by another API key. | no | Check the request ID and use the same API key that created the Generation. |
| 404 | invalid_request_error | not_found | The public route does not exist. | Wrong path or method. | no | Check the stable API reference. |
| 429 | rate_limit_error | rate_limit_exceeded | The key exceeded requests per minute. | Traffic exceeded the configured key limit. | yes | Honor Retry-After and retry with backoff. |
| 429 | rate_limit_error | provider_rate_limit | The upstream Provider rate-limited the request. | Normalized upstream HTTP 429. | yes | Honor retry guidance and use bounded backoff. |
| 500 | internal_error | server_not_configured | The gateway cannot initialize required server configuration. | Temporary service configuration failure. | conditional | Retry later or contact support with the request ID. |
| 500 | internal_error | balance_lookup_failed | Balance verification could not complete. | Transient internal storage failure. | conditional | Retry later and retain the request ID. |
| 500 | internal_error | monthly_spend_lookup_failed | Monthly key spend could not be verified. | Transient usage storage failure. | conditional | Retry later and retain the request ID. |
| 500 | internal_error | model_pricing_lookup_failed | Billing metadata could not be resolved. | Transient pricing lookup failure. | conditional | Retry later or contact support. |
| 500 | billing_error | billing_consistency_error | A successful result could not be billed consistently. | A billing consistency invariant failed. | conditional | Do not assume success; contact support with the request ID. |
| 500 | internal_error | model_list_failed | Callable models could not be listed. | Transient model registry read failure. | conditional | Retry later. |
| 500 | internal_error | usage_lookup_failed | Usage records could not be listed. | Transient usage storage failure. | conditional | Retry later. |
| 500 | internal_error | usage_cost_lookup_failed | Usage cost rows could not be loaded. | Transient billing storage failure. | conditional | Retry later. |
| 500 | internal_error | api_keys_lookup_failed | API key metadata could not be listed. | Transient API key storage failure. | conditional | Retry later. |
| 500 | internal_error | generation_lookup_failed | Generation metadata could not be loaded. | Transient Generation storage failure. | conditional | Retry later and retain the request ID. |
| 500 | internal_error | provider_attempt_create_failed | Qufas could not initialize an upstream attempt record. | Transient internal request-initialization failure. | conditional | Retry selectively and retain the request ID. |
| 500 | internal_error | configuration_error | The selected model has an invalid service-side provider mapping. | Service configuration does not currently permit execution. | no | Do not change a valid request; contact support with the request ID. |
| 502 | provider_error | provider_authentication_error | Qufas could not authenticate to the upstream Provider. | Normalized upstream HTTP 401 or 403. | no | Contact support with the Qufas request ID. |
| 502 | provider_error | provider_bad_request | The upstream Provider rejected Qufas's normalized request. | Normalized upstream 4xx other than timeout or rate limit. | no | Retain the request ID and contact support if the documented request is valid. |
| 502 | provider_error | provider_unavailable | The Provider is temporarily unavailable. | Normalized upstream availability or 5xx failure. | yes | Retry with backoff using the same logical idempotency key. |
| 502 | provider_error | provider_unknown_error | The upstream request failed without a more specific normalized result. | Unknown transport or Provider failure. | conditional | Retry selectively and retain the request ID. |
| 502 | provider_error | provider_error | An image Provider request failed before a normalized result was available. | Generic image Provider transport failure. | conditional | Retry selectively and retain the request ID. |
| 502 | provider_error | provider_stream_error | The upstream stream could not be opened. | Provider stream setup failed before response headers. | conditional | Retry selectively and retain the request ID. |
| 503 | provider_error | provider_not_configured | The selected provider adapter is not configured. | Provider configuration is unavailable. | no | Contact Qufas support with the request ID. |
| 503 | provider_error | all_providers_unavailable | Every configured candidate is unavailable. | Circuit filtering or provider availability. | yes | Retry later; Qufas will not call an OPEN provider. |
| 504 | provider_error | provider_timeout | The upstream provider timed out. | Provider execution exceeded its timeout. | yes | Retry selectively with backoff. |
| SSE | provider_error | provider_timeout | The upstream Provider timed out after streaming headers. | Streaming execution exceeded its timeout. | yes | Treat the stream as failed, retain the request ID, and retry selectively. |
| SSE | provider_error | provider_stream_error | The upstream stream failed after headers. | Provider, malformed chunk, or incomplete upstream stream. | conditional | Treat the stream as failed and retain the request ID. |
| SSE | provider_error | empty_provider_stream | The provider stream opened but produced no usable event. | Empty or prematurely closed upstream stream. | conditional | Treat the stream as failed and retry selectively with backoff. |
| SSE | provider_error | repeated_streaming_chunk_limit | Qufas stopped a stream that repeated the same chunk beyond its safety limit. | Abnormal repetitive upstream output. | conditional | Treat the stream as failed; retry selectively or change the request. |
| SSE | provider_error | malformed_stream_chunk | The provider emitted a chunk that could not be parsed. | Malformed upstream SSE payload. | conditional | Treat the stream as failed and retry selectively with backoff. |
| SSE | billing_error | usage_missing | The stream ended without usage required to finalize billing. | The provider omitted its terminal usage payload. | conditional | Treat the logical operation as failed and retain the request ID before retrying. |
| SSE | internal_error | streaming_error | The streaming response could not be completed. | Unexpected stream-processing failure. | conditional | Treat the stream as failed and retry conditionally with the request ID retained. |
| SSE | insufficient_balance | insufficient_balance | Streaming accounting detected insufficient balance after headers were sent. | The prepaid balance could not cover finalization. | no | Add credits before retrying the logical operation. |
| SSE | billing_error | billing_temporarily_unavailable | Streaming billing finalization is temporarily unavailable. | Transient billing storage failure after headers. | conditional | Treat the logical stream as failed and contact support before blind retry. |
| SSE | billing_error | billing_consistency_error | Streaming billing could not be finalized consistently. | A billing consistency invariant failed. | conditional | Do not assume success; contact support with the request ID. |
Showing 52 of 52 documented public codes.
Provider errors are normalized
Qufas normalizes, redacts, and maps upstream provider failures. Do not parse provider raw messages or depend on provider-specific diagnostics. Use the Qufas status, error code, and x-qufas-request-id.
Retry guidance
Retry 429, 502, 503, and 504 selectively with bounded exponential backoff. Do not retry authentication, permission, validation, or unsupported-parameter errors without changing the request. Streaming in-band errors mean the logical operation did not complete normally.
An SSE error can be followed by [DONE]; the marker ends the stream and does not make the error a success. Client Stop/disconnect is distinct from a provider error and does not guarantee provider cancellation or zero cost. Missing usage can leave settlement incomplete, while a billing/reporting error can occur after a charge commits. Check usage and billing with the request ID before retrying; preserve the same idempotency key for the same logical operation.
Was this page helpful?
