{"record":{"id":"82d91feafbe8aad0","repo":"nautechsystems/nautilus_trader","slug":"method-rpc-error-code","errorCode":null,"errorMessage":"{method} RPC error {code}","messagePattern":"(.+?) RPC error (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/rpc/http.rs","lineNumber":342,"sourceCode":"        let bytes = self\n            .send_rpc_request(request, Some(EXECUTION_RPC_TIMEOUT_SECS))\n            .await\n            .map_err(|e| match e {\n                BlockchainRpcClientError::ClientError(message)\n                    if message.contains(\"redirect response rejected\") =>\n                {\n                    anyhow::anyhow!(\"{method} redirect rejected\")\n                }\n                _ => anyhow::anyhow!(\"{method} request failed\"),\n            })?;\n\n        let parsed = serde_json::from_slice::<RpcNodeHttpResponse<T>>(bytes.as_ref())\n            .map_err(|_| anyhow::anyhow!(\"Failed to parse {method} response\"))?;\n\n        if parsed.jsonrpc.is_none()\n            && let (Some(code), Some(_message)) = (parsed.code, parsed.message)\n        {\n            anyhow::bail!(\"{method} RPC error {code}\");\n        }\n\n        if let Some(error) = parsed.error {\n            anyhow::bail!(\"{method} RPC error {}\", error.code);\n        }\n\n        Ok(parsed.result)\n    }\n\n    /// Returns the chain ID reported by the RPC node via `eth_chainId`.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the RPC call fails or the result is missing or malformed.\n    pub async fn chain_id(&self) -> anyhow::Result<u64> {\n        let result: Option<String> = self\n            .execute_execution_rpc_call(\"eth_chainId\", serde_json::json!([]))\n            .await?;","sourceCodeStart":324,"sourceCodeEnd":360,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/blockchain/src/rpc/http.rs#L324-L360","documentation":"The typed execution-layer RPC call (`chain_id`, `get_storage_at`, `get_code_with_block`, `get_transaction_count_*`) received a non-standard error response containing a top-level `code` but no `jsonrpc` field. Like the untyped path, this indicates a provider-level error (commonly rate limiting on Infura-style endpoints) rather than a JSON-RPC protocol error. Only the code is included in the message here, not the provider message.","triggerScenarios":"A call routed through `execute_execution_rpc_call` gets a response body with `jsonrpc: null` and top-level `code`/`message` — e.g. `eth_chainId` or `eth_getTransactionCount` hitting a rate-limited or misconfigured provider endpoint.","commonSituations":"Flooding a free-tier provider with transaction-count/storage polling loops; wrong provider endpoint returning gateway-level errors; expired project keys producing provider-throttle responses during startup or sync.","solutions":["Back off and retry with exponential delay when the code indicates rate limiting (e.g. 429)","Confirm the RPC URL and API key; test the endpoint with curl to see the raw provider response","Reduce polling frequency or batch/subscribe (WebSocket/`eth_subscribe`) instead of repeated HTTP polls","Route requests through a fallback provider when this error code is observed"],"exampleFix":"// before: tight polling loop\nloop { let n = rpc.get_transaction_count_latest(addr).await?; tokio::time::sleep(Duration::from_millis(50)).await; }\n// after: back off and fall back on provider errors\nloop {\n    match rpc.get_transaction_count_latest(addr).await {\n        Ok(n) => break n,\n        Err(e) if e.to_string().contains(\"RPC error\") => { tokio::time::sleep(backoff.next()).await; continue; }\n        Err(e) => return Err(e),\n    }\n}","handlingStrategy":"retry","validationCode":"// Pre-validate params and throttle request rate:\nfn valid_hex(s: &str, len: usize) -> bool { s.starts_with(\"0x\") && s.len() == len && s[2..].chars().all(|c| c.is_ascii_hexdigit()) }","typeGuard":null,"tryCatchPattern":"match typed_call().await {\n    Err(e) if e.to_string().contains(\"RPC error\") => {\n        tokio::time::sleep(backoff.next()).await; // provider-level error: back off, then fail over\n        retry_or_fallback()\n    }\n    other => other,\n}","preventionTips":["Throttle polling loops (transaction-count/storage checks) below provider limits","Keep RPC URLs/keys current; test endpoints with curl during setup","Use WebSocket subscriptions instead of repeated HTTP polls where possible"],"tags":["rpc","provider-error","rate-limit","ethereum"],"backgroundTag":"rate-limit-exceeded","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}