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
- Verify the clock timestamp is a realistic Unix time (roughly 1e18 nanoseconds, not near u64::MAX) before subscribing to book snapshots
- In tests, avoid advancing the TestClock to values near u64::MAX when snapshot intervals are active
- If a custom clock source is in use, fix its timestamp computation so it returns valid Unix nanoseconds
- 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
- Keep clock timestamps within realistic Unix nanos ranges in production and tests
- Avoid advancing TestClock to values near u64::MAX when timers are scheduled
- Audit custom clock implementations for timestamp computation bugs
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
- Event '{}' should have associated handler
- AtomicTime overflow: reached u64::MAX
- timer event sender was unset for Rust callback system
- DurationNanos overflow in from_millis
- DurationNanos overflow in from_secs
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6bee417c59bd28da.
Report an issue: GitHub.