nautechsystems/nautilus_trader · error
Cannot represent durations greater than 584 years
Error message
Cannot represent durations greater than 584 years
What it means
The mock/quanta clock's advance() converts the Duration to u64 nanoseconds and panics if it exceeds u64::MAX nanoseconds (~584 years). The clock's internal state is a u64 nanosecond counter, so longer jumps are unrepresentable.
Source
Thrown at crates/network/src/ratelimiter/clock.rs:112
///
/// The mock time is represented as an atomic u64 count of nanoseconds, behind an [`Arc`].
/// Clones of this clock will all show the same time, even if the original advances.
#[derive(Debug, Clone, Default)]
pub struct FakeRelativeClock {
now: Arc<AtomicU64>,
}
impl FakeRelativeClock {
/// Advances the fake clock by the given amount.
///
/// # Panics
///
/// Panics if `by` cannot be represented as a `u64` number of nanoseconds (i.e., exceeds 584 years).
pub fn advance(&self, by: Duration) {
let by: u64 = by
.as_nanos()
.try_into()
.expect("Cannot represent durations greater than 584 years");
let mut prev = self.now.load(Ordering::Acquire);
let mut next = prev + by;
while let Err(e) =
self.now
.compare_exchange_weak(prev, next, Ordering::Release, Ordering::Relaxed)
{
prev = e;
next = prev + by;
}
}
}
impl PartialEq for FakeRelativeClock {
fn eq(&self, other: &Self) -> bool {
self.now.load(Ordering::Relaxed) == other.now.load(Ordering::Relaxed)
}View on GitHub (pinned to 18893faf8b)
Solutions
- Cap the advance duration below u64::MAX nanoseconds (~584 years).
- In tests, advance in steps (e.g. loop advancing 1 year) instead of one giant jump.
- Check where the Duration is built; a unit conversion bug (secs treated as nanos, or from_secs_f64 of a huge number) is usually the cause.
Example fix
// before clock.advance(Duration::from_secs_f64(1e12)); // > 584 years in nanos? panics // after let by = Duration::from_secs_f64(1e12); assert!(by.as_nanos() <= u64::MAX as u128, "advance exceeds clock range"); clock.advance(by);
Defensive patterns
Strategy: validation
Validate before calling
fn advance_safe(clock: &QuantaClock, by: Duration) {
assert!(by.as_nanos() <= u64::MAX as u128, "advance exceeds u64 nanos");
clock.advance(by);
} Type guard
fn representable(d: &Duration) -> bool { d.as_nanos() <= u64::MAX as u128 } Try / catch
let result = std::panic::catch_unwind(|| clock.advance(by));
Prevention
- Sanity-check computed durations; check for unit conversion mistakes
- Advance mock clocks in bounded steps in tests
- Never build Durations from unchecked external numeric config
When it happens
Trigger: Calling RateLimiter clock advance(by) (public) with a Duration whose as_nanos() > u64::MAX — practically only with absurdly large Durations; called in tests via test_ensure_window_current and by sleep().
Common situations: Writing tests that simulate long time jumps (e.g. Duration::from_secs(u64::MAX) or from_secs_f64 with huge values); misconfigured timeout/backoff values that overflow when converted to nanos.
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
- Duration is longer than 584 years
- DurationNanos overflow in from_micros
- {e}
- `durations_seconds` value is too large, was {value}
- system clock overflowed when converting to i64
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2a3be78ebb648bb1.
Report an issue: GitHub.