Appearance
Errors
Errors can originate at three layers. The layer is easy to tell apart: gateway errors are non-200 HTTP with a message/error JSON body; RPC-proxy errors are HTTP 200 with a JSON-RPC error object; chain errors are whatever the node itself returns (also HTTP 200 on JSON-RPC chains).
Gateway layer (HTTP status ≠ 200)
| HTTP | When | Body |
|---|---|---|
401 | Missing or unknown apikey header | {"message":"No API key found in request"} / {"message":"Unauthorized"} |
402 | Tenant suspended | {"message":"account suspended — contact your administrator"} |
403 | debug_* method on /eth | {"error":"debug methods not permitted"} |
429 | Plan rate limit exceeded | {"message":"API rate limit exceeded"} + Retry-After |
429 | Heavy-method guard (1/min, /eth) | {"message":"Heavy method rate limit: 1/min for eth_getLogs"} + Retry-After |
RPC-proxy layer (HTTP 200, JSON-RPC error)
| Code | Message | Meaning / what to do |
|---|---|---|
-32700 | invalid JSON-RPC request | Body isn't valid JSON — fix the request |
-32011 | chain "xyz" not in project scope | The project's chains allow-list excludes this chain — adjust the project or use the right key |
-32005 | compute unit quota exceeded | Daily CU budget exhausted — wait for the window or upgrade |
-32601 | unsupported chain: xyz | No such chain path on this deployment |
-32603 | backend request failed | All nodes for the chain are unreachable — retriable; alert us if persistent |
Example:
json
{"jsonrpc":"2.0","error":{"code":-32011,"message":"chain \"bsc\" not in project scope"},"id":1}REST-style chains (TRON, Aptos, Stellar) translate the same conditions to HTTP codes instead: 403 {"error":"chain ... not in project scope"}, 502 {"error":"unsupported chain: ..."} / {"error":"backend request failed"}.
Chain layer (the node speaks)
Passed through verbatim. The common ones:
| Chain family | Example | Meaning |
|---|---|---|
| EVM | {"code":3,"message":"execution reverted"} | Contract reverted your eth_call/estimateGas |
| EVM | {"code":-32000,"message":"nonce too low"} | Transaction nonce already used |
| bitcoind | {"code":-5,"message":"No such mempool or blockchain transaction"} | Unknown txid (use a valid one or add blockhash) |
| bitcoind | {"code":-22,"message":"TX decode failed"} | sendrawtransaction payload isn't valid hex tx |
| bitcoind (BCHN) | {"code":-32601,"message":"Method not found"} | e.g. estimatesmartfee on Bitcoin Cash — use estimatefee |
| rippled | {"result":{"error":"actNotFound"}} | Account not on ledger (rippled errors live inside result) |
| NEAR | {"error":{"cause":{"name":"UNKNOWN_ACCOUNT"}}} | Account doesn't exist |
Retry matrix
| Condition | Retry? | How |
|---|---|---|
429 + Retry-After | yes | wait exactly Retry-After, then once |
-32603 backend request failed | yes | exponential backoff with jitter, ≤3 attempts |
5xx from gateway | yes | exponential backoff with jitter |
-32700, -32011, -32601 | no | fix the request/key/project |
-32005 quota | no (today) | resumes after the 24 h window |
401/402/403 | no | fix credentials / account / method choice |
| Chain-level errors (revert, nonce, decode) | no | application logic, not transport |
A ready-made backoff implementation lives in Batches, retries & caching.
Correlating with support
Every response carries X-Correlation-ID. Include it when you report an issue — it pins your request across gateway and proxy logs.