nautechsystems/nautilus_trader · error

Overflow occurred when multiplying `Quantity`

Error message

Overflow occurred when multiplying `Quantity`

What it means

After checked_mul_div_raw computes the product at the minimum precision, the raw result is filtered against QUANTITY_RAW_MAX; exceeding it panics. Quantity's internal representation (u64 raw) cannot hold the product at the requested precision, so multiplication overflows the type.

Source

Thrown at crates/model/src/types/quantity.rs:753

    }
}

impl Mul for Quantity {
    type Output = Self;
    fn mul(self, rhs: Self) -> Self::Output {
        let result_raw = if self.raw != QUANTITY_UNDEF
            && rhs.raw != QUANTITY_UNDEF
            && self.precision <= FIXED_PRECISION
            && rhs.precision <= FIXED_PRECISION
        {
            checked_mul_div_fixed(self.raw, rhs.raw)
        } else {
            let scalar = QuantityRaw::try_from(raw_scale(self.precision.min(rhs.precision)))
                .expect("Fixed-point scale fits QuantityRaw");
            checked_mul_div_raw(self.raw, rhs.raw, scalar)
        }
        .filter(|raw| *raw <= QUANTITY_RAW_MAX)
        .expect("Overflow occurred when multiplying `Quantity`");

        Self {
            raw: result_raw,
            precision: self.precision.max(rhs.precision),
        }
    }
}

impl Add<Decimal> for Quantity {
    type Output = Decimal;
    fn add(self, rhs: Decimal) -> Self::Output {
        self.as_decimal() + rhs
    }
}

impl Sub<Decimal> for Quantity {
    type Output = Decimal;
    fn sub(self, rhs: Decimal) -> Self::Output {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Validate operand magnitudes before multiplying; use checked_mul or is_valid checks on inputs.
  2. Reduce precision of operands if the product must fit (fewer fractional digits means smaller raw).
  3. Use f64 or a wider decimal type for intermediate math and convert back with Quantity::new_checked.
  4. Reconsider the math — quantity * quantity rarely models a quantity; verify units.

Example fix

// before
let total = qty * factor; // panics when raw exceeds QUANTITY_RAW_MAX
// after
let total = qty.checked_mul(factor).unwrap_or_else(|| {
    eprintln!("quantity multiplication would overflow");
    Quantity::zero(factor.precision)
});
Defensive patterns

Strategy: validation

Validate before calling

fn mul_fits(a: &Quantity, b: &Quantity) -> bool {
    a.raw.checked_mul(b.raw).map(|r| r <= QUANTITY_RAW_MAX).unwrap_or(false)
}

Try / catch

let result = std::panic::catch_unwind(|| a * b)
    .ok()
    .and_then(|q| q.downcast_ref::<Quantity>().cloned());

Prevention

When it happens

Trigger: Calling Quantity::mul on two large quantities (raw values whose product, scaled by raw_scale of the min precision) exceeds QUANTITY_RAW_MAX — e.g. multiplying two quantities with large raw components at high precision.

Common situations: Position/size math on very large notional values or very fine precision instruments; compounding multiplications without bounds checks; accidental unit mistakes (multiplying quantity by quantity instead of scaling).

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/3318bd21bacd3f9a. Report an issue: GitHub.