{"record":{"id":"ce66605f3eb2b1c5","repo":"nautechsystems/nautilus_trader","slug":"eth-call-rpc-error","errorCode":null,"errorMessage":"eth_call RPC error {}","messagePattern":"eth_call RPC error (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/http.rs","lineNumber":560,"sourceCode":"                _ => anyhow::anyhow!(\"eth_call request failed\"),\n            })?;\n        let parsed = serde_json::from_slice::<RpcNodeHttpResponse<String>>(bytes.as_ref())\n            .map_err(|_| anyhow::anyhow!(\"Failed to parse eth_call response\"))?;\n\n        if parsed.jsonrpc.is_none()\n            && let (Some(code), Some(message)) = (parsed.code, parsed.message)\n        {\n            if eth_call_error_is_revert(code, &message) {\n                return Ok(RpcCallResult::Reverted);\n            }\n            anyhow::bail!(\"eth_call RPC error {code}\");\n        }\n\n        if let Some(error) = parsed.error {\n            if eth_call_error_is_revert(error.code, &error.message) {\n                return Ok(RpcCallResult::Reverted);\n            }\n            anyhow::bail!(\"eth_call RPC error {}\", error.code);\n        }\n        let value = parsed\n            .result\n            .ok_or_else(|| anyhow::anyhow!(\"eth_call returned no result\"))?;\n        let stripped = value.strip_prefix(\"0x\").unwrap_or(&value);\n        let bytes = hex::decode(stripped)\n            .map_err(|_| anyhow::anyhow!(\"Failed to decode eth_call response\"))?;\n        Ok(RpcCallResult::Success(Bytes::from(bytes)))\n    }\n\n    /// Estimates the gas required for a transaction via `eth_estimateGas`.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the RPC call fails (including node-side revert of the simulated\n    /// transaction) or the result is missing or malformed.\n    pub async fn estimate_gas(\n        &self,","sourceCodeStart":542,"sourceCodeEnd":578,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/http.rs#L542-L578","documentation":"Raised by `call_result_at` when the RPC response contains a structured `error` object whose code/message is not recognized as a revert. Like error 561 but for the standard `error` field of the JSON-RPC response; the error code is embedded in the message to help identify the node-side failure.","triggerScenarios":"`eth_call` rejected with a structured non-revert error: -32000 execution errors not containing 'revert' (e.g. 'gas required exceeds allowance', 'header not found'), -32603 internal error, -32602 invalid params.","commonSituations":"Querying a block beyond the node's retention ('header not found' on non-archive nodes); gas limit exceeded for complex calls; malformed request params; provider internal errors during high load.","solutions":["Check the embedded error code: -32000 'header not found' → use an archive node or a lower block.","Raise the gas limit/price if the error mentions gas.","Validate parameters passed into the call (address checksums, block encoding) for -32602.","Retry against a different RPC endpoint for -32603 internal errors."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// Ensure the block is within node retention\nlet latest: u64 = provider.request(\"eth_blockNumber\", ()).await?;\nanyhow::ensure!(block <= latest.saturating_sub(REORG_MARGIN), \"block too old for non-archive node\");","typeGuard":"fn is_gas_error(err: &anyhow::Error) -> bool {\n    let s = err.to_string();\n    s.contains(\"gas required exceeds allowance\") || s.contains(\"out of gas\")\n}","tryCatchPattern":"match rpc.call_at(from, to, value, data, block).await {\n    Err(e) if is_gas_error(&e) => retry_with_higher_gas(),\n    Err(e) if e.to_string().contains(\"header not found\") => switch_to_archive_endpoint(),\n    other => other,\n}","preventionTips":["Match node type to query age: archive nodes for old blocks","Set realistic gas caps for complex contract calls","Log the embedded JSON-RPC code from the error message to triage quickly","Retry -32603 internal errors against a second endpoint"],"tags":["evm","rpc","json-rpc","network"],"backgroundTag":"api-error-response","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}