nautechsystems/nautilus_trader · error

eth_getCode returned no result

Error message

eth_getCode returned no result

What it means

The eth_getCode RPC call returned a JSON-RPC result of null (no 'result' field value) for the requested address and block; the node provided no code payload, so the address's deployed bytecode cannot be read and the call fails rather than treating null as empty code.

Solutions

  1. Confirm the node serves state at the requested block (archival node for historical queries)
  2. Retry with block=None (latest) to see if the address has code
  3. Validate the endpoint returns proper JSON-RPC responses (test eth_getCode via curl)
  4. Switch to a node/provider that returns 0x for accounts instead of null

Example fix

// before: historical block on non-archival node
let code = client.get_code_at(&addr, Some(old_block)).await?;
// after: fall back to latest, or ensure archival node
let code = match client.get_code_at(&addr, Some(old_block)).await {
    Ok(c) => c,
    Err(_) => client.get_code(&addr).await?,
};
Defensive patterns

Strategy: fallback

Validate before calling

// check node can serve state at the requested block first
// e.g. call eth_getBlockByNumber(block, false); if null, block is unavailable

Try / catch

let code = match client.get_code_at(&addr, Some(block)).await {
    Ok(c) => c,
    Err(e) if e.to_string().contains("no result") => {
        client.get_code(&addr).await? // fall back to latest state
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling get_code/get_code_at against a node that returns null for the code field — typically a non-compliant node, an error swallowed by a proxy, or a request for a block that is not available (pruned node returning null).

Common situations: Pruned/archival mismatch: requesting code at an old block on a non-archival node; misconfigured endpoint returning null on internal errors.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/937e86bbf3b2b47f. Report an issue: GitHub.

Appendix: source

Thrown at crates/adapters/blockchain/src/rpc/http.rs:419

            )
            .await?;
        let value = result.ok_or_else(|| anyhow::anyhow!("eth_getStorageAt returned no result"))?;
        B256::from_str(&value)
            .map_err(|_| anyhow::anyhow!("Failed to parse eth_getStorageAt response"))
    }

    async fn get_code_with_block(
        &self,
        address: &Address,
        block: Option<u64>,
    ) -> anyhow::Result<Bytes> {
        let result: Option<String> = self
            .execute_execution_rpc_call(
                "eth_getCode",
                serde_json::json!([address, block_parameter(block)]),
            )
            .await?;
        let hex_string = result.ok_or_else(|| anyhow::anyhow!("eth_getCode returned no result"))?;
        let stripped = hex_string.strip_prefix("0x").unwrap_or(&hex_string);
        let bytes = hex::decode(stripped)
            .map_err(|e| anyhow::anyhow!("Failed to decode eth_getCode result: {e}"))?;
        Ok(Bytes::from(bytes))
    }

    /// Returns the next nonce for the given address via `eth_getTransactionCount`
    /// with the `pending` tag, making the pending pool state authoritative.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the result is missing or malformed.
    pub async fn get_transaction_count_pending(&self, address: &Address) -> anyhow::Result<u64> {
        let result: Option<String> = self
            .execute_execution_rpc_call(
                "eth_getTransactionCount",
                serde_json::json!([address, "pending"]),
            )

View on GitHub (pinned to 18893faf8b)