nautechsystems/nautilus_trader · error · anyhow::Error
Maximum gas cost overflow
Error message
Maximum gas cost overflow
What it means
gas_limit * max_fee_per_gas overflowed U256 while computing the worst-case gas cost before signing. Both inputs are bounded (gas limit derives from the node estimate plus a buffer capped by the configured gas_limit; max fee derives from the base fee plus buffer capped by max_fee_per_gas_wei), so an overflow implies wildly misconfigured caps rather than plausible chain values.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:1478
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)
.ok_or_else(|| anyhow::anyhow!("Maximum transaction cost overflow"))?;
let native_balance = self
.http_rpc_client
.get_balance_with_timeout(&self.wallet_address, None, Some(EXECUTION_RPC_TIMEOUT_SECS))
.await?;
if native_balance < max_transaction_cost {
anyhow::bail!(
"Native currency balance {native_balance} wei is below maximum transaction cost {max_transaction_cost} wei"
);
}
let tx = build_eip1559_transaction(
expected_chain_id,
nonce,
gas_limit,View on GitHub (pinned to 2114cf6f76)
Solutions
- Sanity-check the fee config: max_fee_per_gas_wei should be a realistic gwei price scaled to wei (e.g. 100 gwei = 100 * 10**9)
- Bound gas_limit to the block gas limit of the target chain (typically <= 30M)
- Add startup validation rejecting configs whose max_fee_per_gas_wei * gas_limit could approach U256 bounds
Example fix
# before: gwei value written as if it were already scaled, near-overflowing product config.max_fee_per_gas_wei = 10**30 config.gas_limit = 30_000_000 # after: realistic caps (100 gwei ceiling, 1M gas) config.max_fee_per_gas_wei = 100 * 10**9 config.gas_limit = 1_000_000 assert config.max_fee_per_gas_wei * config.gas_limit < 2**128
Defensive patterns
Strategy: validation
Validate before calling
# Startup config sanity: worst-case gas cost must stay far below U256 assert config.max_fee_per_gas_wei <= 1_000 * 10**9, 'max fee above 1000 gwei is a units bug' assert config.gas_limit <= 30_000_000, 'gas limit above a typical block limit is a units bug' assert config.max_fee_per_gas_wei * config.gas_limit < 2**128, 'cost ceiling unrealistic'
Prevention
- Author gas caps in gwei and convert to wei in exactly one place
- Reject configs where max_fee_per_gas_wei or gas_limit exceed plausible chain values at load time
When it happens
Trigger: prepare_and_sign with max_fee_per_gas_wei set near u128::MAX (wrong units, e.g. wei-vs-gwei confusion) combined with a high configured gas_limit, making the product exceed 2^256.
Common situations: Configuring gas prices in wei when the value was already in gwei (10^9 factor); pasting test/sentinel values like 2^127 into the config; generated configs with unbounded defaults.
Related errors
- Maximum transaction cost overflow
- Finalized transaction gas commission overflow
- Pool {instrument_id} fee {fee} exceeds uint24
- Latest block {} has no base fee
- Finalized block timestamp overflows nanoseconds
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/a6184764bb3b1ce4.
Report an issue: GitHub.