nautechsystems/nautilus_trader · error
Failed to decode eth_call response
Error message
Failed to decode eth_call response
What it means
Raised in `call_result_at` when the `result` string of a successful `eth_call` response is not valid hex (after stripping the `0x` prefix). The library expects the node to return a `0x`-prefixed hex-encoded ABI byte string and fails fast when the value cannot be hex-decoded into `Bytes`.
Source
Thrown at crates/adapters/blockchain/src/rpc/http.rs:567
{
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);
}
let value = parsed
.result
.ok_or_else(|| anyhow::anyhow!("eth_call returned no result"))?;
let stripped = value.strip_prefix("0x").unwrap_or(&value);
let bytes = hex::decode(stripped)
.map_err(|_| anyhow::anyhow!("Failed to decode eth_call response"))?;
Ok(RpcCallResult::Success(Bytes::from(bytes)))
}
/// Estimates the gas required for a transaction via `eth_estimateGas`.
///
/// # Errors
///
/// Returns an error if the RPC call fails (including node-side revert of the simulated
/// transaction) or the result is missing or malformed.
pub async fn estimate_gas(
&self,
from: &Address,
to: &Address,
value: U256,
data: &[u8],
) -> anyhow::Result<u64> {
self.estimate_gas_with_block(from, to, value, data, None)
.awaitView on GitHub (pinned to 18893faf8b)
Solutions
- Print/log the raw `result` string from the failing call to see what the node actually returned
- Validate the node returns spec-compliant `0x`-prefixed hex (test with a simple eth_call against eth_chainId-style data)
- Switch to a standards-compliant execution client (geth/reth/erigon) or mainstream provider
- If odd-length hex comes from your own ABI encoding, fix the encoder before sending the request
Defensive patterns
Strategy: validation
Validate before calling
// Pre-validate node hex compliance with a known call
let v: serde_json::Value = send_raw(rpc_url, json!({"jsonrpc":"2.0","method":"eth_chainId","id":1})).await?;
let hex_ok = v["result"].as_str().map(|s| s.starts_with("0x") && hex::decode(&s[2..]).is_ok()).unwrap_or(false); Type guard
fn is_hex_bytes(s: &str) -> bool {
let t = s.strip_prefix("0x").unwrap_or(s);
!t.is_empty() && t.len() % 2 == 0 && t.chars().all(|c| c.is_ascii_hexdigit())
} Try / catch
match client.call_at(&tx, block).await {
Ok(res) => Ok(res),
Err(e) if e.to_string().contains("Failed to decode eth_call response") => {
Err(anyhow!("node returned non-hex eth_call result; check client compliance: {e}"))
}
Err(e) => Err(e),
} Prevention
- Use standards-compliant execution clients (geth/reth/erigon) or mainstream providers
- Sanity-check node hex output at startup with a probe call
- Fix ABI encoders that emit odd-length or unprefixed hex
- Beware proxies that rewrite response bodies between node and client
When it happens
Trigger: The node returns a `result` that is not hex, e.g. an empty string, a non-hex error text smuggled into `result`, odd-length hex, or a decimal value from a non-conforming node.
Common situations: Custom or older execution clients that return unprefixed or odd-length hex; a node returning error text in `result` after an upstream proxy mangled the response; contract ABI output truncated by response size limits.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- eth_call execution reverted
- Failed to execute eth call RPC request: {e}
- Failed to decode eth_getCode result: {e}
- eth_call redirect rejected
- eth_call request failed
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/92d074183403c377.
Report an issue: GitHub.