nautechsystems/nautilus_trader · error · anyhow::Error

Latest block {} has no base fee

Error message

Latest block {} has no base fee

What it means

prepare_and_sign builds an EIP-1559 transaction, which requires a base fee; latest_block.base_fee_per_gas was None. That field is only populated on chains that implement EIP-1559 fee markets, so the connected network (or a degenerate block response) does not provide baseFeePerGas and the transaction cannot be fee-priced.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:1462

    ) -> anyhow::Result<PreparedTransaction> {
        let expected_chain_id = u64::from(self.chain_id);
        let actual_chain_id = self.http_rpc_client.chain_id().await?;
        if actual_chain_id != expected_chain_id {
            anyhow::bail!(
                "Chain ID mismatch: expected {expected_chain_id}, node reported {actual_chain_id}"
            );
        }

        let nonce = self
            .http_rpc_client
            .get_transaction_count_pending(&self.wallet_address)
            .await?;
        self.database
            .assign_execution_intent_nonce(intent_id, nonce)
            .await?;
        let latest_block = self.http_rpc_client.latest_block().await?;
        let base_fee_per_gas_wei = latest_block.base_fee_per_gas.ok_or_else(|| {
            anyhow::anyhow!("Latest block {} has no base fee", latest_block.number)
        })?;
        let priority_fee_per_gas_wei = self.http_rpc_client.max_priority_fee_per_gas().await?;
        let (max_fee_per_gas, max_priority_fee_per_gas) = derive_fees(
            base_fee_per_gas_wei,
            priority_fee_per_gas_wei,
            self.base_fee_buffer_bps,
            u128::from(self.max_fee_per_gas_wei),
        )?;
        let gas_estimate = self
            .http_rpc_client
            .estimate_gas(&self.wallet_address, &to, value, &input)
            .await?;
        let gas_limit = derive_gas_limit(gas_estimate, self.gas_buffer_bps, self.gas_limit)?;
        let max_gas_cost = U256::from(gas_limit)
            .checked_mul(U256::from(max_fee_per_gas))
            .ok_or_else(|| anyhow::anyhow!("Maximum gas cost overflow"))?;
        let max_transaction_cost = value
            .checked_add(max_gas_cost)

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Verify the target chain supports EIP-1559: eth_getBlockByNumber('latest') must include baseFeePerGas
  2. Fix http_rpc_url / chain config so it points at the intended EIP-1559 network (Ethereum mainnet, most L2s)
  3. For private chains, upgrade/enable the London fork on the nodes, since the client signs only EIP-1559 transactions

Example fix

# before: legacy chain, no base fee
block = w3.eth.get_block('latest')
block.get('baseFeePerGas')  # None -> Latest block has no base fee

# after: preflight the endpoint before trading
block = w3.eth.get_block('latest')
assert 'baseFeePerGas' in block, 'chain lacks EIP-1559; pick another endpoint'
config.http_rpc_url = 'https://<eip1559-endpoint>'
Defensive patterns

Strategy: validation

Validate before calling

from web3 import Web3

w3 = Web3(Web3.HTTPProvider(config.http_rpc_url))
latest = w3.eth.get_block('latest')
assert 'baseFeePerGas' in latest and latest['baseFeePerGas'] is not None, (
    'target chain lacks EIP-1559 base fee; the client only signs EIP-1559 transactions'
)

Type guard

def chain_supports_eip1559(block: dict) -> bool:
    return block.get('baseFeePerGas') is not None

Prevention

When it happens

Trigger: prepare_and_sign on a pre-EIP-1559 chain (no London hardfork) or a network whose blocks omit baseFeePerGas; an RPC gateway returning a stripped eth_getBlockByNumber response; a misconfigured http_rpc_url that lands on such a network.

Common situations: Pointing the adapter at private/consortium chains (Besu/Geth in legacy mode, older forks) or testnets without EIP-1559; fat-fingered RPC URLs selecting a different network than intended.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21). Data as JSON: /api/errors/2fae65c071de94c8. Report an issue: GitHub.