RPC errors
The JSON-RPC and HTTP error contract for Starkscan RPC — codes, envelopes, backoff, and fail-closed classes.
RPC errors
After an authenticated request reaches the RPC handler, Starkscan returns a
JSON-RPC 2.0 result or error object. An HTTP authentication rejection also
uses a JSON-RPC error member, so standard clients such as starknet.js throw
normally. Authentication still uses the appropriate HTTP status and
WWW-Authenticate challenge. The gateway rejects authentication before it
trusts the request envelope, so these errors use "id": null.
Transport & protocol codes
| Code | Meaning | When |
|---|---|---|
-32700 | Parse error | Malformed JSON body |
-32600 | Invalid request | Bad envelope; authentication_invalid for malformed or conflicting authentication headers; also batch_too_large (>50 items) with data.maxItems. Do not retry an unchanged authentication request. |
-32601 | Method not found | Method not in the allowlist (e.g. a mistyped starknet_* name) |
-32602 | Invalid params | Params fail validation (shape, bounds, felt format) |
-32603 | Internal error | Unexpected server error (rare; carries a request id) |
Starknet errors
When the upstream node answers with an error the Starknet JSON-RPC spec lists
for that method, such as 20 contract not found, 24 block not found, 29
transaction hash not found, 33 invalid continuation token, 40 contract
error, or 41 transaction execution error, Starkscan returns it exactly as the
spec defines it: the spec's canonical message and, only for codes whose spec
defines one, the spec's data. starknet.js and starknet.go decode the
revert reason normally:
{"jsonrpc":"2.0","id":1,"error":{"code":41,"message":"Transaction execution error","data":{"transaction_index":0,"execution_error":{"contract_address":"0x…","class_hash":"0x…","selector":"0x…","error":"… ('ERC20: transfer amount exceeds balance')"}}}}40carriesdata.revert_error;41carriesdata.transaction_indexanddata.execution_error. Both keep the call chain down to the raised error. A raised error longer than 16 KiB is cut and ends with[truncated by Starkscan]; a chain deeper than 64 frames ends with[call chain truncated by Starkscan]in place of its next frame. Codes whose spec defines nodata, such as24or29, carry none.- Spec errors carry no Starkscan metadata. Use the
X-Request-Idresponse header in a support report. - A spec error is the node's answer, not an outage: a reverting estimate does
not slow down or saturate any other request. When a provider reports an
outage, overload, or rate limit under a spec code, or answers
starknet_blockNumber/starknet_blockHashAndNumberwith32(no blocks), Starkscan returns the retryable-32005upstream_unavailableerror instead, so it is never mistaken for a revert or an empty chain. - Any other upstream error keeps the redacted gateway envelope:
"message":"Starknet RPC upstream rejected the request"witherror.data.code=upstream_json_rpc_error. - Write-submission rejections keep a redacted envelope with
error.data.code=upstream_write_rejected, because their data can echo signatures and calldata.
Gateway-specific JSON-RPC codes
These codes are emitted by the Starkscan gateway. An upstream provider can also
return its own JSON-RPC codes, so branch on the structured error.data.code
when you need the precise condition.
| Code | error.data.code | Meaning | Client action |
|---|---|---|---|
-32004 | unsupported_chain | The URL names a chain this endpoint does not serve. | Correct the URL; do not retry unchanged. |
-32005 | upstream_unavailable, local_saturation, authorization_unavailable, or batch_response_too_large | The upstream or authorization provider is temporarily unavailable, the gateway is saturated, or an aggregate batch result exceeded 16 MiB. | Honor Retry-After when present; split an oversized batch before retrying. |
-32010 | rate_limited | The RPC quota for the request or batch item is exhausted. | Honor the delay and reduce request rate. |
-32011 | write_scope_required | A write method needs an eligible write scope. | Use an eligible key and an already-signed payload; do not retry unchanged. |
-32012 | authentication_required or scope_required | The key is missing or invalid, or a read/simulation request needs the documented access scope. | Use an eligible key; do not retry unchanged. |
Authentication errors on non-2xx
POST /api/v1/{chain}/rpc returns a JSON-RPC error object for authentication
failures while preserving HTTP 400, 401, 403, or 503. HTTP 401 and
403 retain WWW-Authenticate; retryable 503 responses retain Retry-After
when the failed authentication path supplies a delay:
{"jsonrpc":"2.0","id":null,"error":{"code":-32012,"message":"Authentication required","data":{"code":"authentication_required","requestId":"mzk-…","service":"starkscan_rpc_gateway","httpStatus":401}}}REST routes retain the REST error envelope. requestId is also emitted as the
X-Request-Id header on every route. Include it in any support report.
Backoff
Endpoint cooldown before any upstream response returns local_saturation.
If the same request already received an upstream error and cooldown prevents
its retry, Starkscan retains that failure under its normal error-priority and
redaction rules rather than replacing it with local saturation. This applies
to single reads and read batches; it does not increase retry or waiting limits.
- Inspect every JSON-RPC item for an
errorobject, including batch responses with HTTP200. A large history, simulation or trace batch is admitted in chunks, solocal_saturationcan affect only some of its children; retry just those items. The reasonbatch_deadlinemarks children that were not sent because the batch used up its time budget; retry them in a smaller batch. - Honor
Retry-Afterwhenever it is present, regardless of the HTTP status. Gateway throttling and local saturation also expose the delay aserror.data.retryAfterSeconds. - Do not hot-loop when no retry delay is supplied; treat it as a bounded transient failure and apply your own capped backoff.
X-Ratelimit-Limit/-Remaining/-Policylet you pace before you hit the ceiling.X-Starkscan-Rpc-Classtells you which budget a method draws from.
Bounded-payload errors
Large-payload methods fail closed with a typed error instead of returning an oversized body — split the request and retry (no blind loops):
| Method | Cap | Error |
|---|---|---|
starknet_getEvents | chunk_size of at most 1,024 | code 31 PAGE_SIZE_TOO_BIG, exactly as the spec defines it; request at most 1,024 events per page |
starknet_getStorageProof | 32 total proof targets; per-field sub-caps | storage_proof_response_too_large |
starknet_getCompiledCasm | 4 MiB serialized item | compiled_casm_response_too_large |
starknet_traceTransaction, starknet_traceBlockTransactions | 16 MiB serialized item | trace_response_too_large |
| batch | 50 items and 16 MiB aggregate serialized response | batch_too_large or batch_response_too_large |
trace_response_incomplete means the upstream trace omitted or malformed a
field required by the Starknet trace schema. Starkscan rejects that response
instead of returning incomplete execution evidence.
Fail-closed classes
Methods outside the current success surface return an explicit error naming the class — they never partially succeed:
starknet_traceTransaction/starknet_traceBlockTransactionswithout an operator-issuedtraceentitlement or enrolled trace-certified partner policy →rpc_trace; both entitlement forms use separate bounded quotasstarknet_subscribe*/starknet_unsubscribeover HTTP →rpc_ws(use the WSS route)- write methods without a write-scoped key →
rpc_write
What to include in a bug report
HTTP status · the JSON-RPC result or error · X-Request-Id ·
X-Starkscan-Rpc-Class · X-Ratelimit-* · whether you used header or node-URL
auth. Never include the full key or the full node-URL.