nautechsystems/nautilus_trader · error · anyhow::Error
Failed converting gas limit to u64
Error message
Failed converting gas limit to u64
What it means
calculate_fee_from_gas computes the fee as gas_price * gas_limit using Decimal arithmetic, then converts the gas limit back to u64 for the cosmrs Fee. If the Decimal gas limit cannot be represented as u64 (e.g. it is negative, fractional, or exceeds u64::MAX), the conversion fails and this error is returned.
Source
Thrown at crates/adapters/dydx/src/grpc/builder.rs:96
if let Some(gas) = gas_used {
self.calculate_fee_from_gas(gas)
} else {
Ok(Self::default_fee())
}
}
/// Calculate fee from gas usage.
fn calculate_fee_from_gas(&self, gas_used: u64) -> Result<Fee, anyhow::Error> {
let gas_multiplier = Decimal::try_from(GAS_MULTIPLIER)?;
let gas_limit = Decimal::from(gas_used) * gas_multiplier;
// Gas price for dYdX (typically 0.025 adydx per gas)
let gas_price = Decimal::new(25, 3); // 0.025
let amount = (gas_price * gas_limit).ceil();
let gas_limit_u64 = gas_limit
.to_u64()
.ok_or_else(|| anyhow::anyhow!("Failed converting gas limit to u64"))?;
let amount_u128 = amount
.to_u128()
.ok_or_else(|| anyhow::anyhow!("Failed converting gas cost to u128"))?;
Ok(Fee::from_amount_and_gas(
Coin {
amount: amount_u128,
denom: self
.fee_denom
.parse()
.map_err(|e| anyhow::anyhow!("Invalid fee denom: {e}"))?,
},
gas_limit_u64,
))
}
/// Get default fee (zero fee).View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the gas limit passed to calculate_fee is a non-negative whole number Decimal within u64 range (practically <= ~1.8e19, real txs use far less).
- Sanity-clamp the gas estimate before calling: if gas_limit <= 0 or > a sane ceiling, fix the estimation source.
- Check where the gas value originates (simulation response vs hardcoded default) and correct unit conversion there.
- If a fractional gas value comes from averaging estimates, round it (e.g. .ceil()/.round()) before calling.
Example fix
// before let gas_limit = Decimal::new(-5, 0); // negative -> conversion fails // after let gas_limit = Decimal::from(2_000_000u64); // valid whole-number gas limit
Defensive patterns
Strategy: validation
Validate before calling
fn valid_gas_limit(g: Decimal) -> bool {
g.is_sign_positive() && g.fract().is_zero() && g <= Decimal::from(u64::MAX)
} Try / catch
let fee = client.calculate_fee(instrument_id, gas_limit)
.map_err(|e| {
if e.to_string().contains("gas limit to u64") {
// clamp/fix gas estimate at the source
}
e
})?; Prevention
- Clamp gas estimates to a sane ceiling (e.g. 50_000_000) before fee calculation
- Round fractional gas values before passing Decimals
- Validate upstream simulation responses for unit errors
When it happens
Trigger: Calling calculate_fee (-> calculate_fee_from_gas) with a gas_limit Decimal that is negative, non-integer, or greater than 2^64-1.
Common situations: A misconfigured or corrupted gas estimate (e.g. gas limit parsed from an API response with unexpected units); passing a fractional Decimal like 0.5; an upstream simulation returning an absurdly large gas figure.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- Failed converting gas cost to u128
- Transaction broadcast failed: code={}, log={}
- Invalid fee denom: {e}
- Failed to convert price to u64
- Failed to convert quantity to u64
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/9c62656ab4763ffe.
Report an issue: GitHub.