nautechsystems/nautilus_trader · error

raw wei value exceeds unsigned 128-bit range

Error message

raw wei value exceeds unsigned 128-bit range

What it means

Quantity::from_wei converts a raw wei U256 into u128 with try_into().expect("raw wei value exceeds unsigned 128-bit range") because Quantity stores non-negative 128-bit fixed-precision values. Amounts above u128::MAX panic with this message. The library throws it since it cannot represent the quantity losslessly.

Source

Thrown at crates/model/src/defi/types/quantity.rs:39

impl Quantity {
    /// Constructs a [`Quantity`] from a raw amount expressed in wei (18-decimal fixed-point).
    ///
    /// The resulting [`Quantity`] will always have `precision` equal to `18`.
    ///
    /// # Panics
    ///
    /// Panics if the supplied `raw_wei` cannot fit into an **unsigned** 128-bit integer (this
    /// would exceed the numeric range of the internal `QuantityRaw` representation).
    #[must_use]
    pub fn from_wei<U>(raw_wei: U) -> Self
    where
        U: Into<U256>,
    {
        let raw_u256: U256 = raw_wei.into();
        let raw_u128: u128 = raw_u256
            .try_into()
            .expect("raw wei value exceeds unsigned 128-bit range");

        Self::from_raw(raw_u128, 18)
    }

    /// Converts this [`Quantity`] to a wei amount (U256).
    ///
    /// Only valid for prices with precision 18. For other precisions convert to precision 18 first.
    ///
    /// # Panics
    ///
    /// Panics if the quantity has precision other than 18.
    #[must_use]
    pub fn as_wei(&self) -> U256 {
        assert!(
            self.precision == 18,
            "Failed to convert quantity with precision {} to wei (requires precision 18)",
            self.precision
        );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Check raw_wei <= U256::from(u128::MAX) before calling from_wei and reject/flag the amount otherwise.
  2. Confirm the amount is in raw wei units, not already human-scaled (double-scaling inflates values).
  3. Filter the token/instrument upstream if its magnitudes exceed the supported range.
  4. Request a big-number quantity representation upstream if such values are legitimate.

Example fix

// before
let qty = Quantity::from_wei(raw_wei); // panics if raw > u128::MAX
// after
let qty = if raw_wei <= U256::from(u128::MAX) {
    Quantity::from_wei(raw_wei)
} else {
    return Err("quantity wei exceeds u128".to_string());
};
Defensive patterns

Strategy: validation

Validate before calling

fn qty_wei_in_range(raw_wei: U256) -> bool {
    raw_wei <= U256::from(u128::MAX)
}

Type guard

fn to_qty_raw(raw: U256) -> Option<u128> {
    raw.try_into().ok()
}

Prevention

When it happens

Trigger: Calling Quantity::from_wei with raw_wei > u256::MAX; typically huge token amounts from high-decimals tokens, summed balances overflowing 128 bits, or a U256 value that was sign-extended/negative before conversion.

Common situations: Processing ERC-20 transfers for tokens with very large supplies (e.g. meme tokens with 10^40+ units), aggregating portfolio balances, or decoding malformed calldata into a uint256 quantity.

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


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