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

# Error reference

> Complete error code reference for WebSocket and REST endpoints.

Use this reference to diagnose and handle Relayer errors. Three categories exist: WebSocket control errors (subscribe/unsubscribe), transaction relay errors (gasless V3), and transaction broadcast errors.

## Error response format

The Relayer returns errors as JSON messages. Control action errors use `"fail"` status. Transaction action errors include a `failed` array with per-transaction details.

### Control action error (subscribe / unsubscribe)

```json theme={"system"}
{
  "action": "subscribe",
  "status": "fail",
  "reason": "topic limit reached"
}
```

### Transaction action error (relay / broadcast)

```json theme={"system"}
{
  "action": "relay",
  "status": "failed",
  "requestId": "relay-001",
  "hashes": [],
  "failed": [
    { "index": 0, "reason": "missing relayer" }
  ]
}
```

## WebSocket-level errors

The Relayer returns these errors in response to `subscribe`, `unsubscribe`, or malformed control messages.

| Error                             | Description                                                                                             | Resolution                                                                   |
| --------------------------------- | ------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
| `topic limit reached`             | The connection already has 64 active topic subscriptions                                                | Unsubscribe from unused topics before subscribing to new ones                |
| `rate limit exceeded`             | You sent more than 64 control messages within a 5-second window                                         | Implement client-side rate limiting. Batch subscriptions at connection open. |
| `invalid bech32 address in topic` | The address in an `address/{bech32}` topic failed bech32 decode or is not a valid `erd1...` address     | Validate addresses before subscribing                                        |
| `unknown topic`                   | The topic string does not match any supported pattern                                                   | Check the [supported topics](/relayer/overview) list                         |
| `message too large`               | A single WebSocket frame exceeded 4 MB                                                                  | Split large batch payloads into smaller messages                             |
| `unknown action`                  | The `action` field does not match a supported action (`subscribe`, `unsubscribe`, `relay`, `broadcast`) | Use a supported action string                                                |

<Warning>
  A `rate limit exceeded` error closes the connection. Reconnect with exponential backoff and reduce your control message frequency.
</Warning>

## Transaction relay errors

These errors appear in `failed[].reason` of a `relay` response. Each corresponds to a specific validation failure in the co-signing pipeline.

| Error                                             | Description                                                                            | Resolution                                                                                                                                   |
| ------------------------------------------------- | -------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `missing relayer`                                 | The transaction object lacks a `relayer` field                                         | Add the `relayer` field set to the [shard-specific relayer address](/relayer/transaction-relaying#shard-routing-table) before the user signs |
| `shard mismatch: sender_shard=X, relayer_shard=Y` | The sender's shard and the provided relayer address shard differ                       | Use shard derivation to select the correct relayer address. See [shard routing](/relayer/transaction-relaying#shard-routing-table).          |
| `unconfigured relayer`                            | The `relayer` field contains an address not recognized as a deployed shard relayer key | Use only the addresses listed in the [shard routing table](/relayer/transaction-relaying#shard-routing-table)                                |
| `signing capacity exceeded, try again later`      | The Relayer's signing queue is full                                                    | Back off and retry with exponential backoff starting at 500 ms                                                                               |
| `aggregator shutdown`                             | The internal transaction aggregator is shutting down                                   | Reconnect after a brief delay; the Relayer is restarting                                                                                     |

## Transaction broadcast errors

These errors appear in `failed[].reason` of a `broadcast` response. The network or the Relayer's pre-validation returns them when rejecting a transaction.

| Error                  | Description                                                                               | Resolution                                                                                                                     |
| ---------------------- | ----------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `invalid signature`    | The `signature` does not match the canonical serialization of the transaction             | Verify the signing serialization matches the MultiversX specification. Confirm all required fields are present before signing. |
| `invalid nonce`        | The nonce is already consumed or too far ahead of the current account nonce               | Fetch the current nonce from the API before constructing the transaction                                                       |
| `insufficient balance` | The sender account lacks enough EGLD to cover `value + gasPrice * gasLimit`               | Check account balance before sending                                                                                           |
| `invalid receiver`     | The `receiver` field is not a valid bech32 address                                        | Validate the receiver address client-side before submitting                                                                    |
| `gas limit too low`    | `gasLimit` is below the minimum required for the transaction type                         | Use gas estimation from the MultiversX SDK or increase `gasLimit`                                                              |
| `invalid chain id`     | The `chainID` does not match the target network (for example, `"T"` submitted to mainnet) | Set `chainID` to `"1"` for mainnet                                                                                             |

## Subscription response codes

These appear in the `status` field of acknowledgments for subscribe and unsubscribe actions.

| Status | Meaning                                                  |
| ------ | -------------------------------------------------------- |
| `ok`   | The action succeeded                                     |
| `fail` | The action failed. Check the `reason` field for details. |

## Handling errors in code

```ts theme={"system"}
ws.onmessage = (event) => {
  const msg = JSON.parse(event.data);

  // Control action error
  if (msg.status === "fail") {
    console.error(`Action "${msg.action}" failed: ${msg.reason}`);

    if (msg.reason === "rate limit exceeded") {
      // Stop sending control messages for the remainder of the 5-second window
      scheduleRetry(5000);
    }

    if (msg.reason === "topic limit reached") {
      // Prune stale subscriptions before adding new ones
      pruneSubscriptions();
    }

    return;
  }

  // Transaction action errors
  if ((msg.action === "relay" || msg.action === "broadcast") && msg.failed?.length > 0) {
    for (const failure of msg.failed) {
      console.error(`TX[${failure.index}] failed: ${failure.reason}`);

      if (failure.reason === "signing capacity exceeded, try again later") {
        retryWithBackoff(failure.index);
      }

      if (failure.reason?.startsWith("shard mismatch")) {
        console.error("Shard mismatch: check relayer address selection logic");
      }
    }
  }
};
```

## Operational checks

* **Check `status` and `failed` in every response.** Assume nothing succeeded until confirmed.
* **Correlate with `requestId`.** Include a unique `requestId` in every `relay` and `broadcast` action so you can match responses to requests.
* **Validate before sending.** Check bech32 addresses, nonces, and shard assignment client-side to avoid round-trip errors.
* **Implement exponential backoff.** For `signing capacity exceeded` and rate limit errors, start at 500 ms and cap at 30 seconds.
* **Log error reasons.** The `reason` strings are stable and machine-parseable. Use them for automated error handling.
