nautechsystems/nautilus_trader · error

Verified decision block {} has no base fee

Error message

Verified decision block {} has no base fee

What it means

After verifying the decision block header, the client requires `base_fee_per_gas` to compute EIP-1559 max fee/priority fee. If the verified header carries no base fee (None), fee derivation is impossible, so the client aborts the pre-sign flow naming the offending block number.

Source

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

            );
        }
        let decision_ancestry = self.verify_decision_ancestry(decision_header).await?;
        validate_transaction_authorization(authorization, to, value, &input)?;
        let deployment_verification = required_verification(
            self.verification
                .verify_deployment_manifest(&self.deployment_manifest, decision_header.number)
                .await,
            "pre-sign deployment manifest",
        )?;
        let authorization_decisions = match authorization {
            Some(authorization) => {
                self.verify_transaction_authorization(authorization, decision_header.number)
                    .await?
            }
            None => Vec::new(),
        };
        let base_fee_per_gas_wei = decision_header.base_fee_per_gas.ok_or_else(|| {
            anyhow::anyhow!(
                "Verified decision block {} has no base fee",
                decision_header.number
            )
        })?;
        let priority_fee_verification = required_verification(
            self.verification.verify_priority_fee().await,
            "pre-sign priority fee",
        )?;
        let priority_fee_per_gas_wei = priority_fee_verification.value;
        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_verification = required_verification(
            self.verification
                .verify_gas_estimate(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use a chain/RPC that supports EIP-1559 (London hardfork activated) so headers include base_fee_per_gas.
  2. Check the verification provider configuration so full modern headers are returned, not legacy/stripped ones.
  3. Ensure the decision block is a recent block, not genesis or a pre-London historical block.
  4. Update the node/client software if it predates EIP-1559 header support.
Defensive patterns

Strategy: validation

Validate before calling

pub fn header_is_eip1559(h: &VerifiedBlockHeader) -> bool {
    h.base_fee_per_gas.is_some()
}

Type guard

fn has_base_fee(h: &VerifiedBlockHeader) -> Option<u64> { h.base_fee_per_gas }

Try / catch

match result {
    Err(e) if e.to_string().contains("has no base fee") => return Err(config_error("chain must have EIP-1559 activated")),
    other => other,
}

Prevention

When it happens

Trigger: `prepare_and_sign_with_anchors` obtains a decision header whose `base_fee_per_gas` field is None — e.g. verifying a pre-London (pre-EIP-1559) block, a header source that omits the field, or a genesis/legacy header used as the decision block.

Common situations: Pointing the client at a chain that never activated EIP-1559 (or an old archive snapshot); a verification provider returning stripped/partial headers; misconfigured node or RPC that serves legacy block format.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


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