Skip to content

Error Reference

Error responses from Caracal services follow a consistent JSON envelope:

{
"error": "error_code",
"description": "Human-readable explanation"
}

The TypeScript SDK raises CaracalError with code and description fields. The Python SDK raises CaracalError with the same fields. The Go SDK returns typed *CaracalError values with Code and Description.


Returned by the Gateway and STS when mandate validation fails. Always accompanied by a WWW-Authenticate: Bearer header on 401 responses.

CodeHTTPCauseResolution
missing_token401Authorization header is absent or emptyInclude a valid Authorization: Bearer {mandate} header
invalid_token401JWT is malformed, expired, or has an invalid signatureObtain a fresh mandate from the STS; check system clock sync
invalid_zone401zone_id in the JWT does not match the zone expected by this serviceVerify the mandate was issued for the correct zone; check zone_id in config
session_revoked401The session identified by sid has been revokedRe-authenticate to create a new session
insufficient_scope403The mandate does not include a scope required by the resourceRequest a mandate with the required scope; check resource binding configuration
agent_required403The resource requires an agent session but the mandate is a user or application sessionUse an agent session mandate for this operation
delegation_required403The resource requires a delegated mandate but no delegation chain is presentObtain a mandate through the delegation flow before calling this resource
chain_mismatch403The delegation chain in the JWT is inconsistent with the delegation graphRe-obtain the mandate; the graph may have changed since the mandate was issued
hop_count_exceeded403The delegation chain has more hops than the max_hops caveat allowsReduce delegation depth; check max_hops constraints on parent delegation edges

Returned by the STS and API for request-level or server-level failures.

CodeHTTPCauseResolution
access_denied403OPA policy evaluated the request and returned a deny decisionReview the active policy set for the zone; check the principal’s granted scopes
invalid_token400Token exchange input is malformed or contains an invalid claimValidate the input token format and claims before submitting
resource_not_found404The requested zone, session, policy, or resource does not existVerify the resource ID; check that the resource was created before referencing it
internal_error500Unhandled server errorCheck service logs; retry with exponential backoff
policy_eval_failed500OPA returned evaluation_status other than "complete"Check OPA health and the policy bundle; verify the OPA container is running and responsive
provider_rate_limited429An upstream provider has rate-limited this serviceBack off and retry; check provider-specific rate limit configuration
interaction_required401The current session lacks sufficient assurance for this operationRe-authenticate with elevated assurance before retrying
sts_unavailable503The STS did not respond or returned an errorCheck STS health at GET http://localhost:8080/ready; restart if necessary
credential_expired_not_renewable401The credential used for authentication has expired and cannot be renewedRe-authenticate with a valid credential
payload_too_large413The request body exceeds the size limitReduce payload size; check if the operation can be split into smaller requests

Returned by the Coordinator with HTTP 429 when any agent session limit is exceeded.

CodeHTTPLimit exceededResolution
agent_zone_limit_exceeded429Active sessions in the zone reached MAX_PER_ZONE (default: 50)Terminate idle agent sessions before creating new ones; raise MAX_PER_ZONE if appropriate
agent_limit_exceeded429Active sessions for the application reached MAX_PER_APP (default: 200)Terminate idle agent sessions; raise MAX_PER_APP if appropriate
agent_children_limit_exceeded429The parent agent has reached MAX_CHILDREN (default: 10) child sessionsTerminate completed child sessions before spawning new ones
agent_depth_limit_exceeded429The delegation chain has reached MAX_DEPTH (default: 10)Redesign the agent hierarchy to use fewer nesting levels

The Gateway records specific denial reasons in its metrics. These are not returned to clients directly (clients receive an auth error code instead), but they appear in GET /metrics:

Metric fieldTrigger
denials_missing_authNo Authorization header
denials_bad_bearerBearer token malformed
denials_expiringMandate TTL expired
denials_bad_routingNo matching binding for the request path
denials_path_traversalPath traversal detected in the request URI
denials_signatureJWT signature verification failed
denials_jti_replayJTI already seen — replay attempt or clock skew
denials_revokedSession revoked
denials_bindingScope or resource binding does not match

import { CaracalError } from '@caracal/core';
try {
await client.spawn(/* ... */);
} catch (err) {
if (err instanceof CaracalError) {
console.log(err.code); // e.g. "agent_children_limit_exceeded"
console.log(err.description); // human-readable explanation
console.log(err.statusCode); // HTTP status (if from an HTTP response)
}
}
from caracalai_sdk import CaracalError
try:
await client.spawn(...)
except CaracalError as e:
print(e.code) # e.g. "agent_children_limit_exceeded"
print(e.description) # human-readable explanation
import "github.com/garudex/caracal/packages/core/go/errors"
result, err := client.Spawn(ctx, opts)
if err != nil {
var cerr *errors.CaracalError
if errors.As(err, &cerr) {
fmt.Println(cerr.Code) // e.g. "agent_children_limit_exceeded"
fmt.Println(cerr.Description) // human-readable explanation
}
}

HTTP statusRetry?Strategy
400NoFix the request
401 invalid_tokenYesRefresh mandate, then retry once
401 session_revokedNoRe-authenticate
403NoFix scope or delegation chain
404NoFix resource reference
429YesExponential backoff with jitter; check limit configuration
500 policy_eval_failedNoFix OPA configuration
500 internal_errorYesExponential backoff; alert if sustained
503YesExponential backoff; check service health