nautechsystems/nautilus_trader · error

Reduce-only quantity overflow for order {client_order_id}

Error message

Reduce-only quantity overflow for order {client_order_id}

What it means

For reduce-only orders, the engine recomputes the order's leaves quantity capped by the remaining position size and then computes target = filled_qty + leaves using checked arithmetic. If that addition overflows the Decimal capacity, the resulting order quantity would be invalid, so the engine raises this error during quantity maintenance of the reduce-only order.

Source

Thrown at crates/execution/src/matching_engine/mod.rs:5433

                continue;
            }

            // Re-read after dispatch: synchronous handlers can apply this fill immediately,
            // while pending fills account for a cache that has not acknowledged it yet.
            let position = self.cache.borrow().position(&position.id).map_or_else(
                || position.clone_without_events(),
                |position| position.clone_without_events(),
            );

            let remaining = self.position_quantity_remaining(&order, &position)?;
            if remaining.is_zero() {
                self.cancel_reduce_only_order(&order, filled_order.client_order_id())?;
                continue;
            }

            let leaves = self.parent_capped_leaves(&order, remaining);
            let target = order.filled_qty().checked_add(leaves).ok_or_else(|| {
                anyhow::anyhow!("Reduce-only quantity overflow for order {client_order_id}")
            })?;

            if order.quantity() != target {
                // Quantity maintenance must not re-enter matching while a fill loop is active
                self.generate_order_updated(
                    &order,
                    target,
                    order.price(),
                    order.trigger_price(),
                    None,
                );

                if target == order.filled_qty() {
                    self.cancel_reduce_only_order(&order, filled_order.client_order_id())?;
                } else if self.config.support_contingent_orders
                    && order.contingency_type() == Some(ContingencyType::Ouo)
                {
                    self.sync_ouo_leaves(&order, leaves, filled_order.client_order_id())?;

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Reduce the order/instrument quantity magnitude or precision so filled_qty + capped leaves fits in the Decimal max.
  2. Ensure filled_qty and the capped leaves share the same precision/scale before addition (normalize quantity precisions).
  3. Audit the reduce-only sizing logic: capped leaves should not exceed the position's remaining absolute quantity.
  4. Reproduce with logging of filled_qty and leaves values just before the checked_add to identify the scale explosion.

Example fix

// before: mixed precisions can push target out of range
let leaves = self.parent_capped_leaves(&order, remaining);
let target = order.filled_qty().checked_add(leaves).ok_or(...)?;
// after: normalize precision before computing target
let leaves = leaves.normalize(order.filled_qty().precision);
let target = order.filled_qty().checked_add(leaves).ok_or(...)?;
Defensive patterns

Strategy: validation

Validate before calling

// bound reduce-only sizing before the order reaches the engine
let capped = leaves.min(position.quantity.abs());
let target = order.filled_qty().checked_add(capped);
assert!(target.is_some(), "reduce-only target quantity would overflow");

Try / catch

match engine.iteration(&mut command_queue) {
    Err(e) if e.to_string().starts_with("Reduce-only quantity overflow") => {
        log::error!("{e}; cancelling reduce-only order");
        // cancel the offending order and fix its quantity scale
    }
    other => other,
}

Prevention

When it happens

Trigger: Processing a reduce-only order where parent_capped_leaves returns a value that, added to the order's filled_qty, exceeds Decimal capacity — typically from extreme quantity magnitudes, very high precision, or inconsistent quantity scale between filled_qty and the computed leaves.

Common situations: Backtests with enormous notional quantities on high-precision instruments; an instrument whose configured size precision makes quantity values near the Decimal max; custom adapters feeding inconsistent quantity precisions into fills.

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/8b7bd53a0a2b21fe. Report an issue: GitHub.