nautechsystems/nautilus_trader · error
UnixNanos overflow in from_seconds
Error message
UnixNanos overflow in from_seconds
What it means
`UnixNanos::from_seconds` converts a Unix timestamp in whole seconds to nanoseconds by multiplying with `NANOSECONDS_IN_SECOND` (1e9) using `checked_mul`. If the product overflows u64, the constructor panics, since a UnixNanos timestamp cannot exceed `u64::MAX` nanoseconds (year 2554). The library throws it to fail fast rather than silently wrapping the timestamp.
Source
Thrown at crates/core/src/nanos.rs:430
self.0 / NANOSECONDS_IN_MILLISECOND
}
/// Returns the timestamp as microseconds, truncating sub-microsecond precision.
#[must_use]
pub const fn as_micros(&self) -> u64 {
self.0 / NANOSECONDS_IN_MICROSECOND
}
/// Creates a new [`UnixNanos`] from a second timestamp.
///
/// # Panics
///
/// Panics if the result overflows `u64`.
#[must_use]
pub const fn from_seconds(seconds: u64) -> Self {
match seconds.checked_mul(NANOSECONDS_IN_SECOND) {
Some(nanos) => Self(nanos),
None => panic!("UnixNanos overflow in from_seconds"),
}
}
/// Creates a new [`UnixNanos`] from a millisecond timestamp.
///
/// # Panics
///
/// Panics if the result overflows `u64`.
#[must_use]
pub const fn from_millis(millis: u64) -> Self {
match millis.checked_mul(NANOSECONDS_IN_MILLISECOND) {
Some(nanos) => Self(nanos),
None => panic!("UnixNanos overflow in from_millis"),
}
}
/// Creates a new [`UnixNanos`] from a signed millisecond timestamp.
///View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the value is truly in seconds; if it is in milliseconds use `from_millis`, if nanoseconds use `UnixNanos::new`/`from_raw`.
- Guard the input: reject values greater than `u64::MAX / 1_000_000_000` before the call.
- Use a checked/clamped path: compute `seconds.checked_mul(1_000_000_000)` yourself and handle None.
- Sanity-check timestamps against a plausible range (e.g. 0..=year 2200) at config load time.
Example fix
// before
let ts = UnixNanos::from_seconds(expiry); // may be millis!
// after
let ts = if expiry > 18_446_744_073 {
UnixNanos::from_millis(expiry) // value was actually milliseconds
} else {
UnixNanos::from_seconds(expiry)
}; Defensive patterns
Strategy: validation
Validate before calling
const MAX_UNIXNANOS_SECS: u64 = u64::MAX / 1_000_000_000;
fn valid_epoch_seconds(s: u64) -> bool { s <= MAX_UNIXNANOS_SECS } Type guard
fn unix_nanos_from_seconds(s: u64) -> Option<UnixNanos> {
s.checked_mul(1_000_000_000).map(UnixNanos::new)
} Prevention
- Confirm the unit of every timestamp field; seconds vs millis vs nanos is the top cause of overflow.
- Range-check timestamps at ingestion (e.g. must be <= year 2200).
- Never pass u64::MAX as a sentinel expiry; use Option<UnixNanos>.
When it happens
Trigger: Calling `UnixNanos::from_seconds(s)` with `s > 18_446_744_073` (u64::MAX / 1e9, i.e. timestamps beyond roughly year 2554), so `checked_mul` returns None and the panic arm executes.
Common situations: Parsing epoch seconds from a config/env var where someone entered nanoseconds or milliseconds by mistake; sentinel u64::MAX used for 'no expiry'; deserializing timestamps from external data with wrong units.
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
- UnixNanos overflow in from_millis
- UnixNanos overflow in from_micros
- DurationNanos overflow in from_millis
- DurationNanos overflow in from_secs
- DurationNanos overflow in from_mins
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/b6024abba6e41389.
Report an issue: GitHub.