> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryaeris.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP error reference

> Every structured error the Aeris MCP server returns, with the response envelope shape and how a client should handle each one.

When a tool call fails, the Aeris MCP server returns a stable, structured envelope so your client can branch on the error rather than parse free text. Every code below has its own page with the exact response shape, retry rules, and the fields you can rely on in `details`.

## Response envelope

Every failure — 4xx or 5xx — carries this shape on the response body:

```json theme={"dark"}
{
  "ok": false,
  "request_id": "uuid-v4",
  "tool": "read_overview",
  "error": "Human-friendly message.",
  "error_envelope": {
    "code": "ENTITLEMENT_LOCKED",
    "message": "Human-friendly, one sentence.",
    "docs_url": "https://tryaeris.ai/docs/mcp/errors/entitlement-locked",
    "retryable": false,
    "retry_after_ms": null,
    "details": { }
  }
}
```

The top-level `error` string is kept for backwards compatibility. New clients should read `error_envelope`.

## Codes

| Code                                                       | HTTP | Retryable | Meaning                                         |
| ---------------------------------------------------------- | ---- | --------- | ----------------------------------------------- |
| [`AUTH_REQUIRED`](/mcp/errors/auth-required)               | 401  | no        | Missing or invalid bearer.                      |
| [`AUTH_EXPIRED`](/mcp/errors/auth-expired)                 | 401  | no        | Bearer expired mid-session.                     |
| [`ENTITLEMENT_LOCKED`](/mcp/errors/entitlement-locked)     | 403  | no        | Plan does not include this tool.                |
| [`SCOPE_INSUFFICIENT`](/mcp/errors/scope-insufficient)     | 403  | no        | OAuth grant is missing a required scope.        |
| [`VIEWER_READ_ONLY`](/mcp/errors/viewer-read-only)         | 403  | no        | Admin view-as session — writes disabled.        |
| [`INVALID_INPUT`](/mcp/errors/invalid-input)               | 422  | no        | Input failed schema or business validation.     |
| [`IDEMPOTENCY_REQUIRED`](/mcp/errors/idempotency-required) | 422  | no        | Mutating tool called without `idempotency_key`. |
| [`IDEMPOTENCY_CONFLICT`](/mcp/errors/idempotency-conflict) | 409  | no        | Same key, different payload.                    |
| [`NOT_FOUND`](/mcp/errors/not-found)                       | 404  | no        | Unknown resource, tool, or empty range.         |
| [`CONFLICT`](/mcp/errors/conflict)                         | 409  | no        | Target already in the requested state.          |
| [`RATE_LIMITED`](/mcp/errors/rate-limited)                 | 429  | **yes**   | Per-user or per-org QPS hit.                    |
| [`CONNECTION_EXPIRED`](/mcp/errors/connection-expired)     | 424  | no        | Partner OAuth needs reconnect.                  |
| [`INSUFFICIENT_CREDIT`](/mcp/errors/insufficient-credit)   | 402  | no        | Wallet empty for a paid action.                 |
| [`UPSTREAM_UNAVAILABLE`](/mcp/errors/upstream-unavailable) | 502  | **yes**   | Partner API 5xx / DNS / TLS fault.              |
| [`TIMEOUT`](/mcp/errors/timeout)                           | 504  | **yes**   | Tool exceeded its `timeoutMs`.                  |
| [`INTERNAL`](/mcp/errors/internal)                         | 500  | **yes**   | Unclassified server error.                      |

<Note>
  Codes are stable UPPER\_SNAKE strings. New codes may be added; existing codes will not be renamed inside a major MCP protocol version.
</Note>
