nautechsystems/nautilus_trader · error

Failed to read the consensus finalized block; the execution

Error message

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

What it means

`finalized_block()` calls `block_by_tag("finalized", ...)`, which requires the execution endpoint to support the post-merge `finalized` block tag via `eth_getBlockByNumber`. When the underlying call fails for any reason (unsupported tag, RPC failure, malformed result), the error is re-wrapped with this message telling the operator the endpoint must support the finalized tag.

Source

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

    /// Returns the latest block via `eth_getBlockByNumber` with the `latest` tag.
    ///
    /// # Errors
    ///
    /// Returns an error if the RPC call fails or the result is missing or malformed.
    pub async fn latest_block(&self) -> anyhow::Result<RpcBlock> {
        self.block_by_tag("latest", false).await
    }

    /// Returns the consensus finalized block.
    ///
    /// # Errors
    ///
    /// Returns an error if the endpoint does not support the `finalized` tag, the RPC call
    /// fails, or the result is missing or malformed.
    pub async fn finalized_block(&self) -> anyhow::Result<RpcBlock> {
        self.block_by_tag("finalized", false).await.map_err(|e| {
            anyhow::anyhow!(
                "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?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Upgrade the execution client to a post-merge version supporting the `finalized` tag (geth >= v1.10.x era, reth, etc.)
  2. Ensure the execution node is connected to a consensus client (beacon node) so finalized blocks are known
  3. Check the inner error text (appended after the colon) for the root cause: unsupported tag vs RPC failure vs null result
  4. If the provider does not support `finalized`, use `safe` or `latest` tags where the fork-verification config allows

Example fix

// before: old execution node without finalized tag support
// geth v1.9.x -> upgrade
// after
// geth version >= 1.13 with a connected beacon node
// curl -X POST $RPC -d '{"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["finalized",false],"id":1}'
Defensive patterns

Strategy: fallback

Validate before calling

async fn supports_finalized_tag(url: &str) -> bool {
    send_raw(url, json!({"jsonrpc":"2.0","method":"eth_getBlockByNumber","params":["finalized",false],"id":1}))
        .await.ok()
        .and_then(|v| v.get("result").cloned())
        .map(|r| !r.is_null())
        .unwrap_or(false)
}

Try / catch

let block = match client.finalized_block().await {
    Ok(b) => b,
    Err(e) if e.to_string().contains("finalized") => {
        log::warn!("endpoint lacks finalized tag; falling back to safe/latest");
        client.latest_block().await?
    }
    Err(e) => return Err(e),
};

Prevention

When it happens

Trigger: Calling `finalized_block()` against an execution node that does not implement the `finalized` tag (pre-merge clients, some third-party providers, or a consensus/execution mispair), or the underlying eth_getBlockByNumber call fails or returns null.

Common situations: Running an old geth/erigon version predating finalized-tag support; provider tier that excludes post-merge tags; execution endpoint not wired to a consensus client so no finalized head exists.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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