Error codes
Talos returns structured error responses following the herodot error format. Every error
response includes an id, HTTP status code, status text, and a human-readable message.
Error response format
{
"error": {
"code": 400,
"status": "Bad Request",
"message": "The API key format is invalid.",
"reason": "Additional context about the error"
}
}
Application errors
| Error ID | HTTP | gRPC | Description |
|---|---|---|---|
bad_request | 400 | INVALID_ARGUMENT | The request was malformed or contained invalid parameters |
credential_required | 400 | INVALID_ARGUMENT | A credential is required. |
derived_token_not_revocable | 400 | INVALID_ARGUMENT | Derived tokens cannot be revoked. |
invalid_api_key_format | 400 | INVALID_ARGUMENT | The API key format is invalid. |
invalid_token_type | 400 | INVALID_ARGUMENT | The token type is invalid. |
unknown_credential | 400 | INVALID_ARGUMENT | The credential type is not recognized. |
api_key_expired | 401 | UNAUTHENTICATED | The API key has expired. |
api_key_revoked | 401 | UNAUTHENTICATED | The API key has been revoked. |
parent_key_invalid | 401 | UNAUTHENTICATED | Parent key validation failed. |
signature_invalid | 401 | UNAUTHENTICATED | Signature verification failed. |
unauthorized | 401 | UNAUTHENTICATED | The request could not be authorized |
forbidden | 403 | PERMISSION_DENIED | The requested action was forbidden |
ip_not_allowed | 403 | PERMISSION_DENIED | The request IP is not allowed for this API key. |
payment_required | 403 | PERMISSION_DENIED | The feature is not available and requires payment. |
api_key_not_found | 404 | NOT_FOUND | The API key was not found. |
not_found | 404 | NOT_FOUND | The requested resource could not be found |
api_key_exists | 409 | ALREADY_EXISTS | An API key with this identifier already exists. |
conflict | 409 | ALREADY_EXISTS | The resource could not be created due to a conflict |
failed_precondition | 409 | FAILED_PRECONDITION | The operation cannot be completed due to a failed precondition. |
too_many_requests | 429 | RESOURCE_EXHAUSTED | The request was throttled due to resource exhaustion. |
internal_server_error | 500 | INTERNAL | An internal server error occurred, please contact the system administrator |
service_unavailable | 503 | UNAVAILABLE | The service is temporarily unavailable. |
gateway_timeout | 504 | DEADLINE_EXCEEDED | The operation timed out. |
Standard HTTP errors
| Error ID | HTTP | Description |
|---|---|---|
Standard bad_request | 400 | Generic validation error |
Standard unauthorized | 401 | Authentication required |
Standard forbidden | 403 | Insufficient permissions |
Standard not_found | 404 | Resource not found |
Standard conflict | 409 | Resource conflict |
Standard internal_server_error | 500 | Unexpected server error |
Verification error codes
The VerifyAPIKey response includes an error_code enum when verification fails:
| Code | Meaning |
|---|---|
VERIFICATION_ERROR_UNSPECIFIED | No error (key is valid) |
VERIFICATION_ERROR_INVALID_FORMAT | Credential format is invalid |
VERIFICATION_ERROR_EXPIRED | Credential has expired |
VERIFICATION_ERROR_REVOKED | Credential has been revoked |
VERIFICATION_ERROR_NOT_FOUND | Credential not found in database |
VERIFICATION_ERROR_SIGNATURE_INVALID | Cryptographic signature verification failed |
VERIFICATION_ERROR_INTERNAL | Internal server error during verification |
VERIFICATION_ERROR_IP_NOT_ALLOWED | Request IP is not in the key's allowed CIDR ranges |
VERIFICATION_ERROR_RATE_LIMITED | Rate limit quota exhausted (commercial-only) |
Batch import error codes
The BatchImportAPIKeys response includes per-item error codes:
| Code | Meaning |
|---|---|
BATCH_IMPORT_ERROR_UNSPECIFIED | No error (import succeeded) |
BATCH_IMPORT_ERROR_INVALID_ARGUMENT | The key data is malformed or missing required fields |
BATCH_IMPORT_ERROR_ALREADY_EXISTS | A key with this identifier already exists |
BATCH_IMPORT_ERROR_FAILED_PRECONDITION | State conflict prevents the import |
BATCH_IMPORT_ERROR_INTERNAL | Server error during import |
Error handling recommendations
- 4xx errors: Fix the request and retry. Do not retry without changes.
- 409 Conflict: Check if the resource already exists or is in an incompatible state.
- 5xx errors: Retry with exponential backoff and jitter.
- 503 Service Unavailable: The server is temporarily overloaded. Retry after the
Retry-Afterheader value if present.
