nautechsystems/nautilus_trader · error

Book snapshot timer start exceeds UnixNanos range

Error message

Book snapshot timer start exceeds UnixNanos range

What it means

DataEngine::schedule_book_snapshotter computes the first order-book snapshot timer start by flooring the current Unix nanos to the snapshot interval and adding one interval. checked_add returns None when that start time would exceed the UnixNanos range (u64 nanoseconds), and this expect turns that overflow into a panic. The library throws it because scheduling a timer beyond the representable time domain is unrecoverable in the engine.

Source

Thrown at crates/data/src/engine/mod.rs:4415

            }
        }

        BookSnapshotUnsubscribeResult::Removed
    }

    fn schedule_book_snapshotter(
        &mut self,
        interval_ms: NonZeroUsize,
        snapshot_infos: BookSnapshotInfos,
    ) {
        let interval_ms_u64 =
            u64::try_from(interval_ms.get()).expect("Snapshot interval exceeds u64");
        let interval_ns = DurationNanos::from_millis(interval_ms_u64);
        let now_ns = self.clock.borrow().timestamp_ns();
        let start_time_ns = now_ns
            .floor(interval_ns)
            .checked_add(interval_ns)
            .expect("Book snapshot timer start exceeds UnixNanos range");

        let snapshotter = Rc::new(BookSnapshotter::new(
            interval_ms,
            snapshot_infos,
            self.cache.clone(),
        ));
        let timer_name = snapshotter.timer_name;
        let snapshotter_callback = snapshotter.clone();
        let callback_fn: Rc<dyn Fn(TimeEvent)> =
            Rc::new(move |event| snapshotter_callback.snapshot(event));
        let callback = TimeEventCallback::from(callback_fn);

        self.clock
            .borrow_mut()
            .set_timer_ns(
                &timer_name,
                interval_ns,
                Some(start_time_ns),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the clock timestamp is a realistic Unix time (roughly 1e18 nanoseconds, not near u64::MAX) before subscribing to book snapshots
  2. In tests, avoid advancing the TestClock to values near u64::MAX when snapshot intervals are active
  3. If a custom clock source is in use, fix its timestamp computation so it returns valid Unix nanoseconds
  4. Use a smaller snapshot interval_ms so floor(now) + interval stays within range, though overflow only occurs at extreme timestamps

Example fix

// before
let start_time_ns = now_ns
    .floor(interval_ns)
    .checked_add(interval_ns)
    .expect("Book snapshot timer start exceeds UnixNanos range");
// after
let start_time_ns = now_ns
    .floor(interval_ns)
    .checked_add(interval_ns)
    .ok_or_else(|| DataEngineError::ConfigError(format!(
        "Snapshot timer start {now_ns} + {interval_ns}ns exceeds UnixNanos range"
    )))?;
Defensive patterns

Strategy: validation

Validate before calling

let now_ns = clock.timestamp_ns();
let interval_ns = u64::from(interval_ms_u64) * 1_000_000;
assert!(now_ns.checked_add(interval_ns).is_some(), "clock time plus snapshot interval exceeds UnixNanos range");

Type guard

fn unix_nanos_fits(now_ns: u64, interval_ns: u64) -> bool {
    now_ns.checked_add(interval_ns).is_some()
}

Prevention

When it happens

Trigger: Calling book snapshot subscribe APIs (which reach schedule_book_snapshotter) when clock.timestamp_ns() is so large that now_ns.floor(interval_ns) + interval_ns overflows u64 nanoseconds; also reachable with a TestClock set to a nanos value near u64::MAX, or an extremely large interval_ms that pushes the floored value over the limit.

Common situations: Unit tests that advance a TestClock to absurdly large timestamps near u64::MAX; misconfigured clock sources producing huge nanos values; snapshot intervals combined with a current time at the edge of the representable range.

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/6bee417c59bd28da. Report an issue: GitHub.