nautechsystems/nautilus_trader · critical
System time overflow: value exceeds u64::MAX nanoseconds
Error message
System time overflow: value exceeds u64::MAX nanoseconds
What it means
nanos_since_unix_epoch in crates/core/src/time.rs:136 converts the duration since the Unix epoch to u64 nanoseconds, panicking via expect("System time overflow: value exceeds u64::MAX nanoseconds") when the value exceeds u64::MAX. Since u64 nanoseconds cover roughly the year 2554, this fires only when the system clock is set absurdly far in the future (or a mocked clock misbehaves), which the documented invariant treats as an unrecoverable environment error.
Source
Thrown at crates/core/src/time.rs:136
// running under simulation are always inside a runtime, so they
// continue to receive virtual time.
match madsim::time::TimeHandle::try_current() {
Some(handle) => handle.now_time(),
None => SystemTime::now(),
}
}
}
/// Returns the current UNIX time in nanoseconds, based on [`SystemTime::now()`].
///
/// # Panics
///
/// Panics if the duration in nanoseconds exceeds `u64::MAX`.
#[inline(always)]
#[must_use]
pub fn nanos_since_unix_epoch() -> u64 {
u64::try_from(duration_since_unix_epoch().as_nanos())
.expect("System time overflow: value exceeds u64::MAX nanoseconds")
}
/// Represents an atomic timekeeping structure.
///
/// [`AtomicTime`] can act as a real-time clock or static clock based on its mode.
/// It uses an [`AtomicU64`] to atomically update the value using only immutable
/// references.
///
/// The `realtime` flag indicates which mode the clock is currently in.
/// For concurrency, this struct uses atomic operations with appropriate memory orderings:
/// - **Acquire/Release** for reading/writing in **static mode**.
/// - **Compare-and-exchange (`AcqRel`)** in real-time mode to guarantee monotonic increments.
///
/// The mode flag and timestamp are private so every update flows through the methods
/// that uphold the monotonicity and mode invariants.
#[repr(C)]
#[derive(Debug)]
pub struct AtomicTime {View on GitHub (pinned to 18893faf8b)
Solutions
- Correct the system clock (NTP sync) and verify with `date` before restarting the process.
- Check any simulation/virtual clock seeding code: confirm the epoch offset unit (seconds vs millis vs nanos) and magnitude.
- If a fake clock is used in tests, clamp its advancement so accumulated time stays within u64 nanoseconds.
- Audit NTP sources and time-jump handling; log the clock value at startup to catch absurd settings early.
Example fix
# before (virtual clock seeded in nanos instead of seconds) start = 1_700_000_000_000_000_000 * 1_000 # runaway offset # after start = 1_700_000_000 # seconds since epoch, correct unit
Defensive patterns
Strategy: validation
Validate before calling
use std::time::{SystemTime, UNIX_EPOCH};
let d = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
assert!(u64::try_from(d.as_nanos()).is_ok(), "clock value exceeds u64 nanos; check clock config"); Type guard
fn nanos_fit_u64(d: std::time::Duration) -> bool {
u64::try_from(d.as_nanos()).is_ok()
} Prevention
- Verify the OS clock (`date`) is sane before starting long-running processes.
- Double-check units when seeding simulation/virtual clocks (seconds vs millis vs nanos).
- Clamp mock-clock advancement in tests so accumulated time cannot overflow u64 nanos.
- Audit NTP sources; log the epoch offset at startup to catch absurd values early.
When it happens
Trigger: Calling nanos_since_unix_epoch (via run_impl, abort_run, end, is_within_last_24_hours, etc.) when the OS clock is set past ~year 2554: manual date misconfiguration, NTP serving a wildly wrong time, or a test/virtual clock configured with an out-of-range epoch offset.
Common situations: Typo'd manual date setting (e.g. year 30000); misconfigured mock clock fixtures advancing virtual time by huge multiples; broken NTP servers; deterministic simulation clocks seeded with milliseconds instead of seconds (or vice versa) producing runaway values.
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
- Time went backwards
- heartbeat request timeout should fit in an instant
- Error calling `SystemTime`
- DurationNanos overflow in from_micros
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/06abc81bd01743b1.
Report an issue: GitHub.