nautechsystems/nautilus_trader · error
{method} RPC error {}
Error message
{method} RPC error {} What it means
A typed execution RPC call (`chain_id`, `get_storage_at`, `get_code_with_block`, `get_transaction_count_*`) received a standard JSON-RPC error object from the node. The message includes the method name and the JSON-RPC error code but discards the node's `message` detail, so consult the code (-32601 unsupported method, -32602 invalid params, -32000/-32005 server/limit errors). The node received and rejected the request at protocol level.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:346
BlockchainRpcClientError::ClientError(message)
if message.contains("redirect response rejected") =>
{
anyhow::anyhow!("{method} redirect rejected")
}
_ => anyhow::anyhow!("{method} request failed"),
})?;
let parsed = serde_json::from_slice::<RpcNodeHttpResponse<T>>(bytes.as_ref())
.map_err(|_| anyhow::anyhow!("Failed to parse {method} response"))?;
if parsed.jsonrpc.is_none()
&& let (Some(code), Some(_message)) = (parsed.code, parsed.message)
{
anyhow::bail!("{method} RPC error {code}");
}
if let Some(error) = parsed.error {
anyhow::bail!("{method} RPC error {}", error.code);
}
Ok(parsed.result)
}
/// Returns the chain ID reported by the RPC node via `eth_chainId`.
///
/// # Errors
///
/// Returns an error if the RPC call fails or the result is missing or malformed.
pub async fn chain_id(&self) -> anyhow::Result<u64> {
let result: Option<String> = self
.execute_execution_rpc_call("eth_chainId", serde_json::json!([]))
.await?;
parse_hex_quantity_result("eth_chainId", result)
.and_then(|v| u64::try_from(v).map_err(Into::into))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Decode the error code: fix params for -32602, switch endpoints for -32601, back off for -32005
- Validate all hex params (address length, 32-byte storage slot with 0x prefix) before the call
- For historical block queries, use an archive node instead of a pruned full node
- Retry only transient codes with backoff; add a fallback RPC endpoint for hard failures
Example fix
// before: unvalidated storage slot
let slot = format!("{}", index); // decimal, not 0x-hex32
let v = rpc.get_storage_at(contract, slot, block).await?;
// after
let slot = format!("0x{:064x}", index);
let v = rpc.get_storage_at(contract, slot, block).await?; Defensive patterns
Strategy: validation
Validate before calling
fn valid_slot(slot: &str) -> bool { slot.starts_with("0x") && slot.len() <= 66 && slot[2..].chars().all(|c| c.is_ascii_hexdigit()) }
// format slots as 0x{:064x}, addresses as 0x + 40 hex chars Try / catch
match typed_call().await {
Err(e) if e.to_string().contains("RPC error -32602") => fix_params_and_retry(),
Err(e) if e.to_string().contains("RPC error -32601") => use_alternate_endpoint(),
Err(e) => Err(e),
Ok(v) => Ok(v),
} Prevention
- Encode hex params correctly (0x-prefixed, fixed-width for slots)
- Use archive nodes for historical block queries; pruned nodes reject them
- Match method availability to endpoint type before calling; classify error codes for retry vs hard failure
When it happens
Trigger: `execute_execution_rpc_call` gets a response with a populated `error` field for any of the wrapper methods: e.g. `eth_getStorageAt` with a malformed slot hex, `eth_getCode` at an unsupported block tag on a pruned node, or `eth_chainId` on an endpoint that doesn't expose it.
Common situations: Pruned/light nodes rejecting historical block queries; invalid storage-slot or address hex in params; endpoints that don't support certain methods (some L2/gateway RPCs); node returning -32005 limit exceeded under load.
Related errors
- RPC error {}: {}
- Included wrap transaction {tx_hash} has invalid block number
- RPC provider error {code}: {message}
- {method} RPC error {code}
- eth_call RPC error {code}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/35d452b502aacfdf.
Report an issue: GitHub.