Skip to main content

Error Codes

Every error response from the Qpher API includes a machine-readable error_code that you can use for programmatic error handling, along with a human-readable message.

Error Response Format

All errors follow a consistent structure:

{
"error": {
"error_code": "ERR_KEM_001",
"message": "Invalid encryption request"
},
"request_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2026-01-15T10:30:00.000Z"
}
FieldTypeDescription
error.error_codestringStable, machine-readable code. Format: ERR_<CATEGORY>_###.
error.messagestringHuman-readable description. Do not parse this programmatically — it may change.
request_idstring (UUID)Unique request identifier for tracing and support.
timestampstring (ISO 8601)UTC time when the error occurred.

Error Code Naming Convention

Error codes follow the pattern ERR_<CATEGORY>_<NUMBER>:

CategoryTypical HTTP StatusDomain
AUTH401Authentication failures
INVALID400, 422Input validation errors
FORBIDDEN403Authorization denied
NOT_FOUND404Resource not found
CONFLICT409Duplicate or concurrent operations
RATE_LIMIT429Rate limit exceeded
POLICY403Policy engine denied request
KEM400, 500KEM encryption/decryption errors
KMS400, 404, 409Key management errors
SIG400Signature sign/verify errors
CRYPTO500Internal cryptographic errors
INTERNAL500Unexpected internal errors
BAD_GATEWAY502Downstream service failure
SERVICE503Service unavailable
TIMEOUT504Request timeout

Complete Error Code Reference

Use the search box to filter by error code or description, or select a category from the dropdown.

CodeHTTPCategoryDescriptionResolution
ERR_AUTH_001401AuthenticationMissing or invalid API keyInclude a valid API key in the X-API-Key header
ERR_INVALID_001400ValidationInvalid request bodyCheck request body matches the expected schema
ERR_INVALID_003422ValidationUnprocessable entityVerify field values match expected types and ranges
ERR_FORBIDDEN_001403AuthorizationOperation not allowed for planUpgrade your plan or reduce usage
ERR_NOT_FOUND_001404Not FoundResource not foundVerify the resource ID or key version exists
ERR_CONFLICT_001409ConflictResource already existsUse a unique identifier or update the existing resource
ERR_RATE_LIMIT_001429Rate LimitRate limit exceededWait and retry with exponential backoff
ERR_POLICY_001403PolicyPolicy engine denied requestCheck policy configuration for your tenant
ERR_KEM_001400KEMInvalid encryption requestEnsure plaintext is base64-encoded and key_version is valid
ERR_KEM_002400KEMInvalid decryption requestUse the same key_version that was used for encryption
ERR_KEM_003500KEMEncryption operation failedRetry the request; contact support if persistent
ERR_KMS_001400KMSInvalid key operation requestUse supported algorithms: Kyber768, Dilithium3
ERR_KMS_002404KMSKey not foundList keys to find available versions
ERR_KMS_003409KMSKey version conflictWait for the current rotation to complete
ERR_SIG_001400SignatureInvalid sign requestEnsure message is base64-encoded and key is active
ERR_SIG_002400SignatureInvalid verify requestProvide all required fields for verification
ERR_CRYPTO_001500CryptoCryptographic operation failedRetry the request; contact support if persistent
ERR_INTERNAL_001500InternalInternal server errorRetry with backoff; contact support with request_id
ERR_BAD_GATEWAY_001502GatewayDownstream service errorRetry; check status.qpher.ai for service health
ERR_SERVICE_001503ServiceService unavailable (fail-closed)Retry after a short delay; check status page
ERR_TIMEOUT_001504TimeoutGateway timeoutRetry with a simpler request or contact support

Using Request IDs for Debugging

Every response — success or error — includes a request_id. This ID traces the request through the entire Qpher infrastructure and is essential for debugging.

Always log request IDs

Store the request_id from every API response in your application logs. When something goes wrong, this is the fastest way to get help from the Qpher support team.

Best practices

  1. Log every request ID on your side, even for successful responses. This creates an audit trail you can cross-reference later.

  2. Include the request ID in support tickets. When contacting Qpher support, provide the request_id and the approximate timestamp. This allows the team to locate the exact request in the distributed tracing system.

  3. Send your own request ID by including the X-Request-ID header. The API will use your value instead of generating one, making it easier to correlate requests across your own systems:

curl -X POST https://api.qpher.ai/api/v1/kem/encrypt \
-H "X-API-Key: qph_your_key_here" \
-H "X-Request-ID: my-trace-id-12345" \
-H "Content-Type: application/json" \
-d '{"plaintext": "SGVsbG8=", "key_version": 1}'

Handling Errors in Your Application

Retry strategy

Not all errors should be retried. Use this guide:

Error CategoryRetry?Strategy
ERR_AUTH_*NoFix your API key or credentials.
ERR_INVALID_*NoFix the request payload.
ERR_FORBIDDEN_*NoCheck plan tier or policy configuration.
ERR_NOT_FOUND_*NoVerify the resource exists.
ERR_CONFLICT_*MaybeWait briefly, then retry if the conflict is transient.
ERR_RATE_LIMIT_*YesWait for Retry-After seconds, then retry.
ERR_POLICY_*NoCheck your tenant's policy configuration.
ERR_KEM_* / ERR_SIG_*Depends400 errors: fix input. 500 errors: retry with backoff.
ERR_KMS_*Depends400/404: fix input. 409: wait and retry.
ERR_CRYPTO_*YesRetry with exponential backoff.
ERR_INTERNAL_*YesRetry with exponential backoff.
ERR_BAD_GATEWAY_*YesRetry after a short delay.
ERR_SERVICE_*YesRetry after a short delay. Check status.qpher.ai.
ERR_TIMEOUT_*YesRetry with a simpler request or increased patience.

Exponential backoff example

import time
import requests

def call_with_retry(url, headers, json_body, max_retries=3):
for attempt in range(max_retries):
response = requests.post(url, headers=headers, json=json_body)

if response.status_code == 429:
retry_after = int(response.headers.get("Retry-After", 2 ** attempt))
time.sleep(retry_after)
continue

if response.status_code >= 500:
time.sleep(2 ** attempt)
continue

return response

raise Exception(f"Failed after {max_retries} retries")
Service status

For real-time service health, check status.qpher.ai. Subscribe to incident updates to get notified of outages before they affect your application.