# Error Codes (/aiway/mcp/reference/error-codes)



The MCP connector surfaces failures across three layers: **JSON-RPC protocol errors** (in the response `error` field), **tool-execution errors** (in a normal `result` with `isError: true`), and **HTTP status codes** from the shared HTTP server. This page is the authoritative catalog of every code. For task-focused guidance on detecting and recovering from these layers in client code, see the [Error Handling guide](/aiway/mcp/guides/error-handling).

## The three error layers [#the-three-error-layers]

A single failed `tools/call` can fail at exactly one of three levels. Check them in order — protocol first, then tool result, then transport — because a higher-layer failure short-circuits the lower layers.

| Layer                   | Where it appears            | Example cause                                                |
| ----------------------- | --------------------------- | ------------------------------------------------------------ |
| JSON-RPC protocol error | `error` field (no `result`) | Malformed JSON, unknown method, missing params, auth failure |
| Tool-execution error    | `result.isError: true`      | Reserved channel, agent not found, command timeout           |
| HTTP status             | HTTP response status line   | Broker not ready (503), gateway timeout (504)                |

## JSON-RPC protocol error codes [#json-rpc-protocol-error-codes]

Protocol-level errors mean the request itself was malformed or could not be dispatched. They are returned in the `error` field — there is **no** `result` field. The HTTP status is still `200` (per JSON-RPC convention); the failure is encoded in the body.

| Code     | Constant                | Name                   | Trigger                                                                                        |
| -------- | ----------------------- | ---------------------- | ---------------------------------------------------------------------------------------------- |
| `-32700` | `JSONRPCParseError`     | Parse Error            | Malformed JSON body, or wrong `Content-Type` (e.g. `text/plain` instead of `application/json`) |
| `-32600` | `JSONRPCInvalidRequest` | Invalid Request        | Empty `method` field, or `jsonrpc` version is not `"2.0"`                                      |
| `-32601` | `JSONRPCMethodNotFound` | Method Not Found       | Unknown method name (e.g. `tools/unknown`)                                                     |
| `-32602` | `JSONRPCInvalidParams`  | Invalid Params         | `params` is not an object, or a required tool argument is missing                              |
| `-32603` | `JSONRPCInternalError`  | Internal Error         | Unexpected server-side failure while dispatching the request                                   |
| `-32010` | `jsonrpcAuthError`      | Authentication Failure | Bearer token missing or invalid on the JSON-RPC endpoint (`/mcp`)                              |

`-32700` through `-32603` are the standard JSON-RPC 2.0 reserved codes. `-32010` is a KubeMQ server-defined code shared by the JSON-RPC endpoints (`/mcp`, `/a2a`).

### Error response format [#error-response-format]

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32601,
    "message": "Method not found"
  }
}
```

A parse error that occurs before the request `id` can be read returns `"id": null`:

```json
{
  "jsonrpc": "2.0",
  "id": null,
  "error": {
    "code": -32700,
    "message": "Parse error"
  }
}
```

### Authentication failures (-32010) [#authentication-failures--32010]

When JWT auth is enabled and a request to `/mcp` carries a missing or invalid `Authorization: Bearer` token, the connector returns the JSON-RPC auth code `-32010` with HTTP status `200` — **not** HTTP `401`:

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32010,
    "message": "authentication required"
  }
}
```

<Callout type="info">
  The `-32010` code applies only to JSON-RPC endpoints (`/mcp`, `/a2a`). Standard HTTP/REST endpoints return HTTP `401` for the same auth failure. See [Auth & security](/connectors/reference/auth-and-security) for the shared auth model.
</Callout>

## Tool-execution errors (`isError`) [#tool-execution-errors-iserror]

Tool-level errors are **not** JSON-RPC errors. The request was valid JSON-RPC and was dispatched successfully, but the underlying messaging operation failed. The response carries a normal `result` field with `isError: true`; the human-readable cause is in `result.content[].text`.

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "content": [{ "type": "text", "text": "Agent 'nonexistent' not found" }],
    "isError": true
  }
}
```

This is why robust clients &#x2A;*check for `error` first, then `result.isError`** — a successful protocol response can still describe a failed tool operation.

### Common tool-execution errors [#common-tool-execution-errors]

| Error                      | Affected tools                                                                       | Example message                                                 |
| -------------------------- | ------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
| Reserved channel rejection | `queue_send`, `events_publish`, `events_store_publish`, `command_send`, `query_send` | `"Channel '_AGENTS_reserved' uses a reserved prefix"`           |
| Non-existent agent         | `agent_info`, `agent_send`, `agent_query`                                            | `"Agent 'nonexistent' not found"`                               |
| Timeout exceeded           | `command_send`, `query_send`, `agent_send`, `agent_query`                            | `"Command timed out: no subscriber on channel 'ch' within 10s"` |
| No subscriber available    | `command_send`, `query_send`                                                         | `"Command timed out: no subscriber on channel 'ch' within 10s"` |
| Non-existent channel       | `channel_info`                                                                       | `"Channel 'nonexistent' of type 'queues' not found"`            |

Reserved-channel rejection comes from the shared `_AGENTS_.` prefix guard — see [Channel resolution](/aiway/mcp/guides/channel-resolution).

## HTTP status codes [#http-status-codes]

For a well-formed request, the connector returns HTTP `200` even when the body contains a JSON-RPC error. Other statuses originate from the shared HTTP server layer (middleware chain) before or around tool dispatch.

| Status | Meaning             | When                                                                                                                                                                   |
| ------ | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `200`  | OK                  | All JSON-RPC responses, including error responses and notifications (e.g. `notifications/initialized`, which returns body `{"jsonrpc":"2.0","result":null,"id":null}`) |
| `503`  | Service Unavailable | The broker is not ready; the traffic gate rejects the request                                                                                                          |
| `504`  | Gateway Timeout     | The request deadline elapsed before a response was committed                                                                                                           |

<Callout type="info">
  HTTP `200` is returned even for JSON-RPC error responses. The error is encoded in the JSON body, not the HTTP status line — always parse the body before treating a `200` as success.
</Callout>

## Resolution order [#resolution-order]

When handling a response, evaluate the layers top-down:

1. **Inspect the HTTP status.** A `503` means the broker is not ready (retry with backoff); a `504` means the request timed out.
2. **Check for `error`.** A present `error` field is a JSON-RPC protocol failure — fix the request (or token for `-32010`). Do not look for `result`.
3. **Check `result.isError`.** If `true`, the tool ran but the operation failed; read the cause from `result.content[0].text`.
4. **Otherwise the call succeeded** — the payload is in `result.content`.

## Related [#related]

<Cards>
  <Card title="Error handling guide" href="/aiway/mcp/guides/error-handling" description="Task-focused how-to: detecting layers, timeouts, and retry strategy in client code." />

  <Card title="Endpoints" href="/aiway/mcp/reference/endpoints" description="POST /mcp and GET /mcp endpoint and JSON-RPC method definitions." />

  <Card title="Tools reference" href="/aiway/mcp/reference/tools-reference" description="Full 15-tool catalog with parameters, defaults, and response shapes." />

  <Card title="Auth & security" href="/connectors/reference/auth-and-security" description="JWT Bearer auth, the -32010 code, and CORS across all connectors." />
</Cards>
