nautechsystems/nautilus_trader · error
eth_call request failed
Error message
eth_call request failed
What it means
Catch-all error for `eth_call` requests: any transport error from `send_rpc_request` that is not a rejected redirect (connection failure, timeout, TLS, HTTP errors) is surfaced as "eth_call request failed". The specific cause is not included in the message.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:542
if let Some(from) = from {
call["from"] = serde_json::json!(from);
}
let request = serde_json::json!({
"jsonrpc": "2.0",
"id": 1,
"method": "eth_call",
"params": [call, block_parameter(Some(block))],
});
let bytes = self
.send_rpc_request(request, Some(EXECUTION_RPC_TIMEOUT_SECS))
.await
.map_err(|e| match e {
BlockchainRpcClientError::ClientError(message)
if message.contains("redirect response rejected") =>
{
anyhow::anyhow!("eth_call redirect rejected")
}
_ => anyhow::anyhow!("eth_call request failed"),
})?;
let parsed = serde_json::from_slice::<RpcNodeHttpResponse<String>>(bytes.as_ref())
.map_err(|_| anyhow::anyhow!("Failed to parse eth_call response"))?;
if parsed.jsonrpc.is_none()
&& let (Some(code), Some(message)) = (parsed.code, parsed.message)
{
if eth_call_error_is_revert(code, &message) {
return Ok(RpcCallResult::Reverted);
}
anyhow::bail!("eth_call RPC error {code}");
}
if let Some(error) = parsed.error {
if eth_call_error_is_revert(error.code, &error.message) {
return Ok(RpcCallResult::Reverted);
}
anyhow::bail!("eth_call RPC error {}", error.code);View on GitHub (pinned to 18893faf8b)
Solutions
- Check node health with a lightweight call (eth_chainId) to distinguish transport vs method issues
- Increase the execution RPC timeout or reduce gas/complexity of the call
- Inspect underlying client logs for the concrete transport error
- Add retry with backoff for transient network failures
Example fix
// before: single attempt, opaque failure
let out = client.call_at(&tx, Some(block)).await?;
// after: retry transient failures with backoff
let out = match client.call_at(&tx, Some(block)).await {
Ok(v) => v,
Err(e) if is_transient(&e) => {
tokio::time::sleep(Duration::from_millis(250)).await;
client.call_at(&tx, Some(block)).await?
}
Err(e) => return Err(e),
}; Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: node reachable and responsive
// curl -sf -X POST $URL -H 'Content-Type: application/json' \
// -d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' Try / catch
match client.call_at(&tx, block).await {
Err(e) if e.to_string() == "eth_call request failed" => {
// inspect transport cause via logs; retry transient failures with backoff
}
other => other,
} Prevention
- Implement retry with exponential backoff for eth_call
- Size gas/complexity so calls complete within EXECUTION_RPC_TIMEOUT_SECS
- Monitor provider status pages and maintain fallback endpoints
- Log underlying client errors, since this message omits the cause
When it happens
Trigger: `call_at` failing due to node unreachability, EXECUTION_RPC_TIMEOUT_SECS elapsing, connection reset, DNS failure, or non-redirect HTTP error statuses from the endpoint.
Common situations: eth_call timeouts on heavy contract simulations, node rate limiting or blocking, provider outage, or network partitions between client and node.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- Failed to execute eth call RPC request: {e}
- {method} request failed
- eth_call redirect rejected
- eth_call execution reverted
- Failed to parse eth call response: {e} Raw response: {previe
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/bbf868df46ba4aa7.
Report an issue: GitHub.