Skip to main content
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)

{
  "action": "subscribe",
  "status": "fail",
  "reason": "topic limit reached"
}

Transaction action error (relay / broadcast)

{
  "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.
ErrorDescriptionResolution
topic limit reachedThe connection already has 64 active topic subscriptionsUnsubscribe from unused topics before subscribing to new ones
rate limit exceededYou sent more than 64 control messages within a 5-second windowImplement client-side rate limiting. Batch subscriptions at connection open.
invalid bech32 address in topicThe address in an address/{bech32} topic failed bech32 decode or is not a valid erd1... addressValidate addresses before subscribing
unknown topicThe topic string does not match any supported patternCheck the supported topics list
message too largeA single WebSocket frame exceeded 4 MBSplit large batch payloads into smaller messages
unknown actionThe action field does not match a supported action (subscribe, unsubscribe, relay, broadcast)Use a supported action string
A rate limit exceeded error closes the connection. Reconnect with exponential backoff and reduce your control message frequency.

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.
ErrorDescriptionResolution
missing relayerThe transaction object lacks a relayer fieldAdd the relayer field set to the shard-specific relayer address before the user signs
shard mismatch: sender_shard=X, relayer_shard=YThe sender’s shard and the provided relayer address shard differUse shard derivation to select the correct relayer address. See shard routing.
unconfigured relayerThe relayer field contains an address not recognized as a deployed shard relayer keyUse only the addresses listed in the shard routing table
signing capacity exceeded, try again laterThe Relayer’s signing queue is fullBack off and retry with exponential backoff starting at 500 ms
aggregator shutdownThe internal transaction aggregator is shutting downReconnect 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.
ErrorDescriptionResolution
invalid signatureThe signature does not match the canonical serialization of the transactionVerify the signing serialization matches the MultiversX specification. Confirm all required fields are present before signing.
invalid nonceThe nonce is already consumed or too far ahead of the current account nonceFetch the current nonce from the API before constructing the transaction
insufficient balanceThe sender account lacks enough EGLD to cover value + gasPrice * gasLimitCheck account balance before sending
invalid receiverThe receiver field is not a valid bech32 addressValidate the receiver address client-side before submitting
gas limit too lowgasLimit is below the minimum required for the transaction typeUse gas estimation from the MultiversX SDK or increase gasLimit
invalid chain idThe 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.
StatusMeaning
okThe action succeeded
failThe action failed. Check the reason field for details.

Handling errors in code

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.