nautechsystems/nautilus_trader · error · anyhow::Error

Maximum transaction cost overflow

Error message

Maximum transaction cost overflow

What it means

value + max_gas_cost overflowed U256 while computing the worst-case transaction cost used for the balance check. value is the native ETH attached to the transaction and max_gas_cost is the (already computed) worst-case fee; only values approaching 2^256 can overflow, which for real chains means a misconfigured or nonsensical input amount.

Source

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

        })?;
        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,
            max_fee_per_gas,
            max_priority_fee_per_gas,
            to,

View on GitHub (pinned to 2114cf6f76)

Solutions

  1. Recheck amount units: convert order quantity with the correct token decimals, and keep it under transaction_limits.max_order_amount
  2. Clamp value and fee caps to realistic on-chain magnitudes at config load time
  3. If this fires in tests, replace sentinel near-max values with plausible raw amounts

Example fix

# before: decimals mix-up produces an astronomically large value
value = int(order_qty * 10**18)  # token has 6 decimals -> 10^12x too big

# after: scale by the token's actual decimals and clamp
value = int(order_qty * 10**base_token.decimals)
assert value <= config.max_order_amount
Defensive patterns

Strategy: validation

Validate before calling

# Reject U256-scale native amounts before submission
value_raw = int(order_qty * 10**base_token.decimals)
assert 0 < value_raw <= config.max_order_amount, 'value exceeds max_order_amount (units bug?)'
assert value_raw + (config.gas_limit * config.max_fee_per_gas_wei) < 2**128, 'cost ceiling unrealistic'

Prevention

When it happens

Trigger: prepare_and_sign where the swap/wrap value passed in is astronomically large (unit error, e.g. raw amount computed against the wrong decimals or a Decimal cast that lost its scale) on top of an already-huge max gas cost.

Common situations: Quantity converted with the quote token's 18 decimals instead of the base token's; test fixtures using U256 near-max values; amounts derived from unbounded user input without clamping.

Related errors


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