AXIS Documentation / Integration / Error Codes
Error Codes
VerifiedStructured: error_code + message + error_id
AXIS returns structured errors with a stable error_code machine-readable identifier. Clients should switch on error_code, not on message text.
Response shape
HTTP/1.1 403 Forbidden
{
"error_code": "blocked_by_policy",
"message": "Blocked by policy rule rule-1 (approval_required_batch)",
"error_id": "err_01HG8X..."
}
Request validation
| Code | HTTP | Meaning |
invalid_json | 400 | Request body is not valid JSON |
empty_sql | 400 | SQL field is empty |
missing_field | 400 | Required context field missing |
multi_statement_rejected | 400 | Multiple statements in one payload (default policy) |
oversized_request | 413 | Body exceeds AXIS_MAX_BODY_BYTES |
oversized_sql | 413 | SQL exceeds AXIS_MAX_SQL_BYTES |
rate_limit_exceeded | 429 | Rate limit or burst limit hit |
Parser & classification
| Code | HTTP | Meaning |
parser_error | 400 | SQL could not be parsed |
parser_unsupported_syntax | 400 | Parsed but syntax not supported by the classifier |
unsupported_sql_shape | 400 | SQL shape unsupported (fail-closed) |
unsafe_read_shape | 400 | Write-like read form (SELECT INTO, data-modifying CTE, locking read) |
PARSE_REJECTED_UNTRUSTED_INPUT | 400 | Invalid UTF-8, NUL bytes, mixed encodings, unparseable extended-protocol bind values |
Policy & decisions
| Code | HTTP | Meaning |
blocked_by_policy | 403 | Policy returned BLOCK |
policy_not_loaded | 503 | No active policy loaded |
policy_validation_failed | 400 | Candidate failed validation |
policy_activation_failed | 409 | expected_hash mismatch or activation failure (previous policy kept) |
policy_candidate_not_found | 404 | Candidate version does not exist |
policy_rollback_not_allowed | 409 | Target is rejected or otherwise not rollback-able |
unauthorized_operator | 401/403 | Missing or invalid operator token |
Approvals
| Code | HTTP | Meaning |
approval_not_found | 404 | Unknown approval_id |
approval_expired | 410 | TTL elapsed; not executable |
approval_rejected | 409 | Approval resolved as reject; execution blocked |
approval_resolution_immutable | 409 | Already resolved; one decision per approval |
approval_invalid_decision | 400 | decision value not approve/reject |
approval_store_error | 500 | Approval store failure |
Database & execution
| Code | HTTP | Meaning |
db_connection_failed | 502 | Could not connect to PostgreSQL |
db_query_timeout | 504 | Query exceeded AXIS_DB_QUERY_TIMEOUT_MS; execution_state: unknown |
db_execution_error | 502 | PostgreSQL returned an error; failure evidence recorded |
db_unavailable | 503 | Database unavailable |
Audit & evidence
| Code | HTTP | Meaning |
audit_wal_failure | 500 | WAL write failed — protected writes do not proceed |
audit_corruption_detected | 500 | Hash-chain or continuity corruption found; never silently repaired |
evidence_range_invalid | 400 | Invalid start_seq/end_seq for evidence export |
Prepared statements
| Code | HTTP | Meaning |
session_not_found | 404 | EXECUTE without resolvable session (fail closed) |
prepared_statement_not_found | 404 | Statement name unknown in the session |
prepared_statement_conflict | 409 | PREPARE with an existing name in the session |
session_limit_exceeded | 429 | AXIS_MAX_PREPARED_SESSIONS reached |
Client guidance
- Match on
error_code; log error_id for correlation with AXIS audit records.
- 429 / 413 / 400 validation errors are retryable after client-side fix;
blocked_by_policy and approval_rejected are not.
- After
db_query_timeout, check audit (execution_state) before retrying — the write may have applied.
Related: API Reference · Troubleshooting