Error Codes
Caracal packages and services use a shared machine-readable error shape.
{ "error": "invalid_token", "error_description": "bearer signature invalid", "requestId": "018f...", "details": {}}details appears only when a service or package provides structured context. The same code can be emitted by different surfaces - an access_denied from STS is a policy decision, while an access_denied surfaced by an in-process verifier is a missing scope on an otherwise valid mandate. Use the requestId with the web console Audit decision trace to confirm which surface produced the error before acting.
HTTP Classes
Section titled “HTTP Classes”| Status | Protocol meaning |
|---|---|
400 | Invalid, denied, or held request; transport retry alone will not repair it. |
401 | Credential was absent or not accepted: malformed, expired, wrong issuer/audience, revoked, or replayed. |
403 | Identity was accepted but lacks authority for this operation or management scope. |
404 | Object is absent, hidden by authorization, or an optional operator endpoint is disabled. |
409 | Lifecycle transition conflicts with current state or idempotency history. |
425, 429 | Retryable timing or rate condition; honor Retry-After where provided. |
5xx | Service or dependency failed; use readiness, logs, and requestId. |
Well-Known Codes
Section titled “Well-Known Codes”The Likely source column names the surface that most often emits the code, and First check is the fastest thing to confirm. When a call fails, start from the surface, not the code.
| Code | Meaning | Likely source | First check |
|---|---|---|---|
access_denied | Request is authenticated but not authorized. | STS policy decision, or an in-process verifier scope check. | Run request trace: confirm the active policy set allows the application, Subject, resource, and scopes. |
invalid_token | Token is missing, malformed, expired, invalid, replayed, or fails verification. | Gateway or a resource verifier. | Confirm the mandate is unexpired, the verifier trusts the issuing zone JWKS, and the token was not already consumed. |
invalid_request | Request is malformed or missing a required parameter. | STS exchange, Coordinator, or OAuth request parsing. | Compare the request against the endpoint contract in API Reference. |
invalid_body | Request body failed schema validation. | Admin API or Coordinator body validation. | Read details.issues for the exact field paths and messages. |
resource_not_found | Requested resource does not exist or is unavailable in the current scope. | API, or STS resource resolution. | Confirm the resource identifier and that the resource carries an upstream URL for (zone, resource). |
internal_error | Service failed unexpectedly. | Any service. | Check service readiness and logs for the requestId. |
policy_eval_failed | Policy evaluation failed. | STS policy engine. | Confirm the active policy set compiles and that required input fields are present. |
provider_rate_limited | Provider or provider coordination rate limit denied work. | Gateway upstream or provider coordination. | Inspect provider limits and retry/backoff; confirm the provider grant is active. |
interaction_required | Policy holds the mint for human approval. | STS approval gate. | Wait for the hold to be decided, then retry with the approval id (approval_id on the wire); see Human Approval. |
sts_unavailable | STS could not satisfy an exchange. | STS, or Gateway’s STS circuit. | Run caracal status --ready; confirm STS readiness, JWKS, and policy bundle freshness. |
credential_expired_not_renewable | Credential is too close to expiry or cannot be renewed. | STS provider-token refresh. | Reconnect the provider grant; confirm OAuth refresh configuration. |
payload_too_large | Request body or token exceeded the configured limit. | Gateway or API preflight. | Reduce payload size or adjust the configured limit. |
zone_invalid | Zone claim or route zone is invalid. Emitted as zone_invalid by STS and Gateway; in-process verifiers emit invalid_zone for the same condition. | Gateway or STS. | Confirm the request targets the correct zone and the mandate carries a matching zone claim. |
scope_insufficient | Required scope is missing. Emitted as scope_insufficient by STS and Gateway; in-process verifiers emit insufficient_scope for the same condition. | A resource verifier, or Gateway. | Confirm the resource defines the scope and the active policy authorizes it for this Subject. |
operation_not_permitted | The Gateway operation is not declared on an enforced resource, or its required scope is absent from the mandate. | STS native operation floor, on Gateway-authenticated mandate use. | Declare the operation on the resource (operations), or set operation_enforcement to transport_uniform; confirm the mandate carries the operation’s scope. |
session_required | A verifier requires a governed Session identity. | In-process verifier or verify engine. | Run the call from a Session, not a bare Authority record. |
session_lease_fenced | A newer process generation owns this service Session lease. | Coordinator heartbeat or close. | Stop the stale holder; only the handle returned by the latest attachSession / attach_session / AttachSession may continue. |
session_subject_inactive | The Federated user’s Authority record bound to the Session expired or was revoked. | Coordinator service lease operation. | Stop the Session and federate the user again before starting new attributed work. |
delegation_required | A verifier requires delegated authority. | In-process verifier. | Confirm the call carries a Delegation granting the required scopes. |
chain_mismatch | Delegation chain does not contain a required application/session. | Verifier delegation check. | Inspect the Delegation in the web console; confirm the chain includes the required hop. |
hop_count_exceeded | Delegation hop count exceeds the allowed maximum. | Coordinator or verifier. | Reduce delegation depth or raise the configured hop limit. |
http_request_failed | HTTP call failed before a valid response could be used. | SDK or Gateway upstream call. | Confirm endpoint URL, network reachability, and upstream allowlist. |
config_missing | Runtime or service configuration is missing. | SDK or service startup. | Confirm the runtime profile, secret file, and required environment variables. |
approval_consumed | Another matching retry already spent the Approval. | STS Approval consumption. | Reconcile the intended effect before requesting another Approval. |
idempotency_key_conflict | A durable operation key was reused with different security-relevant input. | Coordinator Session or Delegation creation. | Reuse the original input or create a deliberate new operation ID. |
idempotency_result_inactive | The recorded Session or Delegation result is no longer live. | Coordinator replay. | Reconcile, then use a newly versioned operation ID only for an intentional rerun. |
session_lease_expired | A long-lived Session lease lapsed and the Session is suspended. | Coordinator heartbeat or attach. | Resolve the cause, resume through the control plane, then attach. |
dcr_application_already_bound | A DCR Application already owns its single Session. | Coordinator Session start. | Reuse that Session or register another DCR Application. |
task_session_cannot_start_service | A task Session attempted to parent a long-lived service Session. | Coordinator Session start. | Use a service parent or create a task child. |
Transport packages may map these codes into framework-specific HTTP responses.
SDK Error Classes
Section titled “SDK Error Classes”The SDKs surface failures through four typed classes, so callers branch on types and machine-readable fields instead of message text. The names below are the TypeScript spellings; Python and Go expose the same classes with idiomatic naming.
| Class | Raised by | Carries | Handle it by |
|---|---|---|---|
CaracalError | STS exchanges and mints | code (the table above), httpStatus, requestId, details, isRetryable | Branch on code; isRetryable hints that transport-level congestion and availability failures are worth retrying while policy outcomes are not. |
ApprovalRequiredError | Approval-gated mints | Everything CaracalError does, plus approvalId, state, tier, binding, expiresAt | Let withApproval run the flow, or persist approvalId and resume with waitForApproval. A CaracalError subclass, so generic handlers still catch it. |
CoordinatorError | Session, delegation, and heartbeat calls | status, method, path, retryAfterSeconds | Branch on code: fenced, terminal, and inactive-Subject errors retire the holder; session_lease_expired is resumable after control-plane resume; 401 means the SDK already attempted one credential refresh. |
CredentialsUnavailableError | Clients built on a credentials resolver | - | The resolver returned no usable credential; the call failed closed. Provision or repair the credential source - retrying without it cannot succeed. |
Unknown Failure Surface
Section titled “Unknown Failure Surface”If you only have an SDK error and not the surface, start from the symptom-first Troubleshoot by Symptom. It routes a denied or failing call to the right surface, the object to inspect, and the diagnostic tool to use.
Retry transport congestion and availability failures only when the operation contract is idempotent. Do not automatically retry policy denial, invalid credentials, consumed Approvals, fenced leases, or changed-payload conflicts. STS issuance uses one network attempt because a lost response can hide a successful mint.
Next Step
Section titled “Next Step”Use Configuration Keys when an error points to missing runtime, service, or deployment configuration.

