# Failure behavior

Distinguish policy denial, unavailable evaluation, billing observe-only, and host timeouts.

Updated: 2026-09-22

Canonical: https://docs.kastra.ai/reference/failure-behavior

## An error is not a policy decision

A policy denial with a structured body is different from a network failure, authentication error, unsupported feature, or malformed response. Decode the exact response and inspect the control's own record before inferring what happened from whether a command ran.

## Read the failure at the correct boundary

| Condition | Behavior to expect | Operator action |
| --- | --- | --- |
| Structured policy denial | The connected integration should stop the evaluated action | Inspect the rule and target; do not route around the denial |
| Edge or local MCP evaluation unavailable | Some failures allow work to continue without enforcement | Inspect fail-open telemetry and apply the accepted risk response |
| Proxy decision recording fails before response commitment | Default refusal with `503` and `decision_record_failed` | Handle the structured failure; investigate service health |
| Proxy failure after streaming starts | An error may arrive after text was delivered | Treat output as incomplete and prevent unauthorized tool dispatch |
| HOLD reaches a terminal state | The checkpoint's effective decision and resume contract determine permission | Inspect stored state, expiry, and the integration's resubmission rules |
| Deliberate shadow or billing observe-only | Policy can be evaluated without blocking enforcement | Identify the cause and confirm the intended operational state |

The detailed sections below describe configuration and path exceptions. Use the [operations guide](https://docs.kastra.ai/security/operations) to assign response ownership.

## Edge and local MCP

Hooks and the local gateway preserve availability in several failure cases. Missing login, reachability failures, or parse/discovery errors can allow work to continue without enforcement. Fail-open telemetry records supported failures separately; it is not a normal ALLOW decision in the hash chain.

The hook uses separate evaluation budgets for gating and audit events. A post-action audit failure cannot undo the completed action. The host's own timeout is another boundary. Hermes version support and hook consent, and OpenClaw's configured failure mode, affect what the host does.

## Proxy and direct integrations

The proxy handles transport, provider, policy, and HOLD errors separately. Output may already be partially delivered when a streaming failure occurs. Custom integrations must explicitly implement error behavior and must not retry around a denial by calling the provider or tool directly.

## Decision storage can refuse a request

The current backend defaults to refusing several runtime paths when the decision cannot be recorded. On the proxy before response bytes are committed, this is a `503` with error code `decision_record_failed` and `X-Policy-Decision: UNAVAILABLE`. A committed stream reports an error event; post-output paths can withhold the tool release. Normal direct evaluation also refuses an unrecordable decision with `503`.

An operator can explicitly configure `KASTRA_ENFORCEMENT_FAIL_OPEN` to preserve availability with an unrecorded result. Client hook fail-open behavior is a separate boundary: a server refusal does not prove that a host agent stopped. This change does not make every audit write transactional; the direct evaluation HOLD path still logs a pending-record failure and can return the created checkpoint. Inspect the actual path and record when investigating an approval.

The current `/ready` check compares the database migration version with the migrations shipped by the server. A behind or dirty schema is unhealthy; missing migration metadata is reported as degraded. Confirm the deployed release includes this behavior before depending on it.

## Observe-only is intentional non-enforcement

Shadow mode and billing degradation can both allow an action that policy would otherwise affect. Preserve the reason when presenting activity. Billing-driven observe-only is not proof that the policy is healthy or that a spend cap remains blocking.

## Diagnose a specific incident

Collect the request/tool-use ID, environment, client version, hook or endpoint, timestamp, response, matched rule, and checkpoint state. Check the original action's record, not adjacent decisions. Do not send credentials or raw sensitive payloads in a support request.

## Self-hosted license expiry

An appliance license lapse limits authoring/configuration and new licensed provisioning; it does not switch active runtime policies to hosted billing observe-only. Evaluation, approval/resume and decision recording continue, subject to ordinary policy outcomes, input safety limits and operational failures. [Deployment and recovery contract](https://docs.kastra.ai/reference/self-hosted).
