Failure modes
What each failure looks like to the requesting agent, the approver and the admin. In every case the business write either has not started, or it has been dispatched exactly once and is being reconciled; no failure below causes a second execution.
"Agent sees" is what GET /v1/actions/{id} (or the proxy, MCP tool or SDK) returns. Where to look as an admin is usually Action detail (/app/actions/:aid) and its diagnosis.
Before a decision
| Failure | Agent sees | Approver sees | Admin sees and does |
|---|---|---|---|
| No grant, wrong tenant, resource or operation | denied with no_grant, operation_not_permitted, resource_not_permitted; 403 tenant_mismatch if the body names another tenant | nothing | The denied action in the project's Actions. Fix the grant or admission. |
| Ceiling exceeded | denied, ceiling_exceeded | nothing (no approval is created) | Expected. Ceilings are hard and cannot be overridden. |
| Emergency deny in force | denied, emergency_deny | nothing | The incident that published it. |
| Agent suspended or retired | Its tokens are revoked (401 invalid_token); a new token request is refused with 403 agent_suspended | — | Agent status and reason on Agents. |
| Quota reached | 402 quota_exceeded on submit; existing actions keep working | existing approvals keep working | Usage on the project overview. Nothing is charged without consent. |
| Approval system unreachable during delivery | pending_approval, progress delivery_pending, next_party: approval delivery | nothing yet | Timeline step "Request delivered to approval system" pending with the last delivery error. Retries back off up to 15 min. |
| Delivery failed 8 times (connector misconfigured or disabled, or a declared-only connector type) | pending_approval, progress delivery_pending | nothing | Delivery step failed with the error. Fix the connector; the request then expires at its deadline unless resubmitted. |
| No eligible approver (nobody holds the role, or all are excluded by separation of duties) | pending_approval, progress delivery_pending | — | Delivery error "no eligible finance_approver in tenant …". Assign the role on Members and approvers. |
| Approval system cannot be read back | pending_approval, progress decision_readback_unavailable | Decided in the native system, waiting for Axiom | Retries every 60 s. Check connector health (POST /v1/connectors/{id}/health). |
| Approver denies | denied, approval_denied | Their decision recorded | Decision with approver and source on the timeline. |
| Decision deadline passes | expired, approval_expired | "the decision deadline has passed"; cannot decide | Expected outcome. A new request needs fresh approval. |
| Request changed after the approver opened it | — | 409 conflict (material_change): reload | Nothing changes; the earlier digest cannot be approved. |
| Approver is the agent's owner or sponsor, or authored the rule | — | Cannot decide: separation_of_duties | Assign another approver. |
| Second approver still needed | pending_approval, second_approver_required | "you have already recorded a decision" for the first approver | Approvals show received of required. |
After approval, before dispatch
| Failure | Agent sees | Admin sees and does |
|---|---|---|
| Agent never comes back | approved, progress awaiting_agent_resume, then expired (resume_expired) at the resume deadline | Diagnosis: "The requesting agent: it must resume with the same action ID". Nothing executes without it. |
| Agent resumes before the decision | 409 invalid_state with retry_after_seconds | — |
| Another agent tries to resume | 403 forbidden, wrong_resume_actor | The attempt is on the timeline. |
| Resume with a changed amount or beneficiary | 409 conflict, material_change, changed_fields; action stays approved | — |
| Grant, credential or agent revoked; emergency deny | revoked with grant_revoked, credential_revoked, agent_suspended or emergency_deny | The revocation in the audit log. |
| Policy changed and now needs more approvals | denied, policy_stale | Submit a new request to collect the new approvals. |
| Approver lost their role | denied, approver_ineligible | Restore the role or re-approve on a new request. |
| Execution owned by a customer-hosted gateway | 409 invalid_state "owned by gateway …" from any hosted path (REST, HTTP proxy, MCP proxy, Axiom MCP server) | See Fleet, gateways and cutover. |
| Embedded-SDK service resumed through Axiom (REST, proxy or MCP) | 409 invalid_state: repeat the original request to the provider; nothing is claimed | — |
After dispatch
| Failure | Agent sees | Admin sees and does |
|---|---|---|
| Provider timeout, network error, 5xx, 408 or 429 | outcome_unknown, target_timeout, progress reconciling; proxy answers 504 upstream_timeout | Axiom asks the provider GET /.well-known/axiom/operations/{operation_key}; on a valid attestation the action becomes succeeded/failed (reconciled). Never retried blindly. |
| Provider returns an attestation that does not verify | outcome_unknown | Check the provider's registered outcome keys on the service. |
| Provider returns 2xx without an attestation | succeeded (gateway_observed_success) | Receipt says "gateway observed HTTP 2xx only"; destination confirmed is no. |
| Provider returns 4xx (not 408 or 429) without an attestation | failed (gateway_observed_failure) | Recorded as observed by the gateway, not confirmed by the provider. |
| Provider rejects the business rule with a signed failure | failed (target_failed), destination confirmed; a signed success is target_confirmed | The provider's reason in the outcome detail. |
Reconciliation schedule
After an outcome_unknown, reconciliation asks the provider's lookup endpoint by operation key. Attempt n is followed, if the provider has no authoritative answer, by attempt n + 1 after min(3600, 30 × 2^n) seconds, up to 12 attempts. The 5-minute sweep re-queues an action only if it has made no progress for an hour (covering a lost queue message) and is still under the limit. After 12 attempts the action stays outcome_unknown for an operator: it is never retried blindly and never executes again. Fix the provider's lookup endpoint, or have the provider report its signed outcome with POST /v1/actions/{id}/outcome, to close it. See Missing receipts.
Infrastructure
| Failure | Effect |
|---|---|
| Webhook endpoint down | Deliveries retry up to 10 times, then are marked dead. The agent learns the state at its next poll. Status reads are always authoritative. |
| Gateway partitioned | Its freshness turns stale after 300 s and offline after 15 min. Sensitive writes must stay blocked or pending; incident screens list it under offline gateways. |
| SIEM endpoint failing | Destination failing with last_error and growing lag. The checkpoint does not advance; nothing is lost. See SIEM recovery. |
| Sectigo CA unavailable | Credential revocation in Axiom still succeeds; the certificate revocation failure is logged. Issuing new certificates fails until the CA returns. |
| Unmapped proxy route or tool | HTTP proxy: 403 forbidden, operation_not_permitted. MCP proxy: JSON-RPC error "Unknown tool" (unmapped tools are also hidden from tools/list). Nothing reaches the upstream. |
Service health distinguishes an unavailable approval system (delivery_pending, decision_readback_unavailable) from a denied business action (denied with a reason code). Missing evidence is reported as missing, never as a denial.