nautechsystems/nautilus_trader · error

eth_getBlockByNumber returned block {} for requested block {

Error message

eth_getBlockByNumber returned block {} for requested block {number}

What it means

`block_by_number` requests a block by hex height via `block_by_tag("0x{number:x}")` and then asserts that the block the node returned is actually the requested height. If the node returns a block whose `number` differs (or a recent/pending resolution shifted the tag), the mismatch is reported with both numbers.

Source

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

                "Failed to read the consensus finalized block; the execution endpoint must support the finalized tag: {e}"
            )
        })
    }

    /// Returns a numbered canonical block, optionally with full transactions.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the result is missing or malformed.
    pub async fn block_by_number(
        &self,
        number: u64,
        full_transactions: bool,
    ) -> anyhow::Result<RpcBlock> {
        let block = self
            .block_by_tag(&format!("0x{number:x}"), full_transactions)
            .await?;
        anyhow::ensure!(
            block.number == number,
            "eth_getBlockByNumber returned block {} for requested block {number}",
            block.number
        );
        Ok(block)
    }

    async fn block_by_tag(&self, tag: &str, full_transactions: bool) -> anyhow::Result<RpcBlock> {
        let result: Option<RpcBlockResponse> = self
            .execute_execution_rpc_call(
                "eth_getBlockByNumber",
                serde_json::json!([tag, full_transactions]),
            )
            .await?;
        let response = result.ok_or_else(|| {
            anyhow::anyhow!("eth_getBlockByNumber returned no result for block tag {tag}")
        })?;
        let mut block = response.block;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the node is fully synced (`eth_syncing`) and the requested height is below the chain head
  2. Retry the request; a transient race (e.g. reorg during resolution) usually resolves
  3. Bypass caching proxies or disable response caching for eth_getBlockByNumber
  4. Use a different node/archive provider if heights are pruned or consistently mismatched

Example fix

// before: querying height beyond node head
let block = client.block_by_number(9_999_999_999, false).await?; // node returns its head -> mismatch
// after: clamp to node head first
let head = client.latest_block().await?;
let target = number.min(head.number);
let block = client.block_by_number(target, false).await?;
Defensive patterns

Strategy: retry

Validate before calling

async fn height_in_range(url: &str, number: u64) -> bool {
    let head: u64 = fetch_chain_head(url).await.unwrap_or(0);
    number <= head
}

Try / catch

match client.block_by_number(number, false).await {
    Ok(b) => Ok(b),
    Err(e) if e.to_string().contains("for requested block") => {
        // transient race or unsynced node: retry, then fail over
        tokio::time::sleep(Duration::from_millis(200)).await;
        client.block_by_number(number, false).await
    }
    Err(e) => Err(e),
}

Prevention

When it happens

Trigger: The node resolves the `0x<hex>` tag to a different block than requested — typically a race on a `latest`-style fallback, a node that rounds unsupported heights to latest, or a proxy/node bug returning a neighboring block. Also possible if the node returns block `number` as null for a pruned/unavailable height.

Common situations: Querying a height beyond the node's synced head (node returns latest instead); pruned nodes serving reorg-affected heights; caching proxies serving a stale block for the requested tag.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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