nautechsystems/nautilus_trader · error
UnixNanos overflow in from_millis
Error message
UnixNanos overflow in from_millis
What it means
`UnixNanos::from_millis` converts a millisecond timestamp to nanoseconds via `checked_mul(NANOSECONDS_IN_MILLISECOND)` and panics when the result exceeds u64::MAX. The panic signals that the given millisecond value cannot be represented as UnixNanos; a non-panicking signed variant (`from_millis` on i64 returning Option) exists for error handling.
Source
Thrown at crates/core/src/nanos.rs:443
/// 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.
///
/// Returns `None` if `millis` is negative or the result overflows `u64`.
#[must_use]
pub const fn from_millis_checked(millis: i64) -> Option<Self> {
Self::from_units_checked(millis, NANOSECONDS_IN_MILLISECOND)
}
/// Creates a new [`UnixNanos`] from a microsecond timestamp.
///
/// # Panics
///
/// Panics if the result overflows `u64`.
#[must_use]
pub const fn from_micros(micros: u64) -> Self {View on GitHub (pinned to 18893faf8b)
Solutions
- Check the unit: if the value is already nanoseconds, construct directly with `UnixNanos::new(value)` instead of multiplying again.
- Bound-check `millis <= u64::MAX / 1_000_000` before calling.
- Use the signed/fallible variant that returns Option and handle None.
- Reject implausible timestamps (far beyond current epoch time) during input validation.
Example fix
// before let ts = UnixNanos::from_millis(raw_ts); // raw_ts already in nanos // after let ts = UnixNanos::new(raw_ts); // no unit conversion needed
Defensive patterns
Strategy: validation
Validate before calling
const MAX_UNIXNANOS_MILLIS: u64 = u64::MAX / 1_000_000;
fn valid_epoch_millis(m: u64) -> bool { m <= MAX_UNIXNANOS_MILLIS } Type guard
fn unix_nanos_from_millis(m: u64) -> Option<UnixNanos> {
m.checked_mul(1_000_000).map(UnixNanos::new)
} Prevention
- If values already exceed ~1.8e13 they are probably nanoseconds already; construct directly with UnixNanos::new.
- Validate timestamp plausibility (near current epoch) before conversion.
- Centralize unit conversion in one typed helper per unit.
When it happens
Trigger: Calling `UnixNanos::from_millis(m)` with `m > 18_446_744_073_709` (u64::MAX / 1e6), making the checked multiplication fail and the panic arm run.
Common situations: Feeding an already-nanosecond timestamp into from_millis (double conversion), producing a huge number; timestamps parsed from log lines or broker messages with wrong units; u64::MAX sentinel values for 'never expires'.
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_seconds
- 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/77c802ee48034e6e.
Report an issue: GitHub.