---
title: "Error codes"
description: "All 57 error codes Veefore returns, what each means and what to do about it."
label: "Errors"
generated: "the ERROR_CODES registry in packages/types/src/errors.ts"
---


Every error response has the same shape:

```json
{
  "error": {
    "code": "AUTHORITY_EXCEEDED",
    "message": "Requested action exceeds delegated authority.",
    "request_id": "req_01JAV7YQ4T2K9M3E8H6R5N1XZ0",
    "details": {
      "capability": "refund.create",
      "ceiling": 50000,
      "requested": 120000
    }
  }
}
```

Branch on `code`, never on `message`. Messages are written for humans and are refined over time; codes are a contract. `request_id` is on every response as the `x-request-id` header too, and it is the fastest way to find the matching action and audit records.

:::security Messages are deliberately plain
Error messages never contain secret values, key material, internal hostnames or stack detail. When you need to know *why* a decision went the way it did, read the action record — it carries the full explanation, behind authentication.
:::

The live table is also served at `GET /v1/meta/error-codes`, with no authentication, so a client can validate its own handling against the deployment it talks to.

## 400 Bad request

The request was malformed or inconsistent. Retrying the same payload will fail the same way. `NONCE_REPLAYED` and `TIMESTAMP_OUT_OF_WINDOW` are the exception: they mean your assertion was reused or your clock has drifted, so sign a fresh one.

| Code | Message |
| --- | --- |
| `VALIDATION_FAILED` | Request validation failed. |
| `INVALID_REQUEST` | The request could not be processed. |
| `INVALID_STATE_TRANSITION` | The requested state transition is not permitted. |
| `INVALID_POLICY` | The policy definition is invalid. |
| `INVALID_CREDENTIAL_REFERENCE` | The credential reference is not usable. |
| `NONCE_REPLAYED` | Request nonce has already been used. |
| `TIMESTAMP_OUT_OF_WINDOW` | Request timestamp is outside the acceptance window. |

## 401 Not authenticated

No usable identity was presented. For agents this almost always means the key was rotated or revoked, or the audience in the assertion does not match the gateway’s published audience exactly.

| Code | Message |
| --- | --- |
| `UNAUTHENTICATED` | Authentication is required. |
| `INVALID_CREDENTIALS` | Authentication failed. |
| `SESSION_EXPIRED` | Session has expired. |
| `AGENT_AUTHENTICATION_FAILED` | Agent authentication failed. |
| `AGENT_TOKEN_EXPIRED` | Agent credential has expired. |
| `AGENT_IDENTITY_REVOKED` | Agent identity has been revoked. |
| `IDENTITY_GENERATION_STALE` | Agent credential was superseded by a rotation. |

## 402 Subscription

Veefore’s own subscription state, not anything to do with your agents’ activity.

| Code | Message |
| --- | --- |
| `SUBSCRIPTION_REQUIRED` | An active Veefore subscription is required. |

## 403 Refused

Identity was established and the request was refused anyway. This is the interesting class: the reason is always specific, always recorded, and always visible in the action record. Do not retry; either change the request or change the authority behind it.

| Code | Message |
| --- | --- |
| `PERMISSION_DENIED` | You do not have permission to perform this action. |
| `STEP_UP_REQUIRED` | Step-up authentication is required for this action. |
| `MFA_REQUIRED` | Multi-factor authentication is required. |
| `TENANT_MISMATCH` | The resource does not belong to the active organization. |
| `NETWORK_RESTRICTED` | Access from this network is not permitted. |
| `ACTION_BLOCKED` | The action was blocked by policy. |
| `AUTHORITY_EXCEEDED` | Requested action exceeds delegated authority. |
| `CAPABILITY_NOT_GRANTED` | The agent does not hold the required capability. |
| `DELEGATION_INVALID` | The delegation chain is not valid for this request. |
| `DELEGATION_EXPIRED` | The delegation has expired. |
| `DELEGATION_ESCALATION` | A delegation may not exceed the authority of its parent. |
| `AGENT_NOT_OPERATIONAL` | The agent is not in an operational state. |
| `AGENT_ISOLATED` | The agent is isolated and cannot perform protected actions. |
| `ENVIRONMENT_PAUSED` | The environment is paused. |
| `TOOL_DISABLED` | The requested tool is disabled. |
| `TOOL_NOT_AUTHORIZED` | The agent is not authorized to use this tool. |
| `DESTINATION_BLOCKED` | The destination is not permitted. |
| `APPROVAL_REQUIRED` | Human approval is required before this action can execute. |
| `APPROVAL_NOT_GRANTED` | The referenced approval does not authorize this request. |
| `APPROVAL_EXPIRED` | The approval has expired. |
| `TRUST_EVIDENCE_INSUFFICIENT` | Required trust evidence is missing or expired. |
| `PASSPORT_INVALID` | The agent passport could not be verified. |
| `MCP_SERVER_NOT_TRUSTED` | The MCP server is not authorized. |
| `A2A_CONNECTION_BLOCKED` | The A2A connection is blocked. |
| `VELOCITY_LIMIT_EXCEEDED` | Velocity limit exceeded for this agent. |

## 404 Not found

No resource with that identifier in this tenant.

| Code | Message |
| --- | --- |
| `NOT_FOUND` | The requested resource was not found. |

## 409 Conflict

The request raced another one, or an idempotency key was reused with a different body. Read current state before retrying.

| Code | Message |
| --- | --- |
| `CONFLICT` | The request conflicts with the current state. |
| `ALREADY_EXISTS` | A resource with that identifier already exists. |
| `VERSION_CONFLICT` | The resource was modified by another request. |
| `IDEMPOTENCY_KEY_REUSED` | This idempotency key was used with a different payload. |

## 410 Gone

The resource existed and no longer does.

| Code | Message |
| --- | --- |
| `GONE` | The resource is no longer available. |

## 422 Unprocessable

Well-formed but not satisfiable as specified.

| Code | Message |
| --- | --- |
| `UNPROCESSABLE` | The request could not be completed as specified. |

## 429 Rate limited

Back off and retry with jitter. Honour `Retry-After` when present.

| Code | Message |
| --- | --- |
| `RATE_LIMITED` | Too many requests. Please retry later. |

## 500 Internal error

Quote the `request_id` from the error body when reporting it.

| Code | Message |
| --- | --- |
| `INTERNAL_ERROR` | An internal error occurred. |

## 502 Downstream error

Veefore permitted the action and the downstream system rejected it. The decision was allowed; the execution was not.

| Code | Message |
| --- | --- |
| `EXECUTION_FAILED` | The downstream system returned an error. |

## 503 Dependency unavailable

A dependency enforcement relies on is down, so protected actions are refused rather than waved through. This is the fail-closed design working as intended, not a bug.

| Code | Message |
| --- | --- |
| `DEPENDENCY_UNAVAILABLE` | A required dependency is unavailable. |
| `IDENTITY_SERVICE_UNAVAILABLE` | Identity verification is unavailable; protected actions are blocked. |
| `POLICY_SERVICE_UNAVAILABLE` | Policy evaluation is unavailable; protected actions are blocked. |
| `APPROVAL_SERVICE_UNAVAILABLE` | Approval service is unavailable; approval-gated actions cannot execute. |
| `CREDENTIAL_SERVICE_UNAVAILABLE` | Credential broker is unavailable; dependent actions cannot execute. |
| `AUDIT_SERVICE_UNAVAILABLE` | Audit pipeline is unavailable. |

## 504 Downstream timeout

The downstream system did not respond inside the egress timeout. Whether it applied the side effect is unknown, which is exactly why mutating tools should be idempotent.

| Code | Message |
| --- | --- |
| `EXECUTION_TIMEOUT` | The downstream system did not respond in time. |
