nautechsystems/nautilus_trader · error
seconds {secs} is out of range for `u64` nanoseconds
Error message
seconds {secs} is out of range for `u64` nanoseconds What it means
secs_to_nanos multiplies seconds by 1e9 and stores the result in u64, whose maximum is ~1.8446744e19 nanoseconds (about 584 years). This error means the input seconds, converted to nanoseconds, exceeds the u64 upper bound, so the conversion would overflow.
Source
Thrown at crates/core/src/datetime.rs:236
/// Converts seconds to nanoseconds (ns).
///
/// # Errors
///
/// Returns an error if `secs` is non-finite or cannot be represented as `u64` nanoseconds.
#[expect(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_precision_loss,
reason = "Intentional for unit conversion, may lose precision after clamping"
)]
pub fn secs_to_nanos(secs: f64) -> anyhow::Result<u64> {
anyhow::ensure!(secs.is_finite(), "seconds must be finite, was {secs}");
if secs <= 0.0 {
return Ok(0);
}
let nanos = secs * NANOSECONDS_IN_SECOND as f64;
anyhow::ensure!(
nanos < U64_UPPER_BOUND_F64,
"seconds {secs} is out of range for `u64` nanoseconds"
);
Ok(nanos.trunc() as u64)
}
/// Converts seconds to milliseconds (ms).
///
/// # Errors
///
/// Returns an error if `secs` is non-finite or cannot be represented as `u64` milliseconds.
#[expect(
clippy::cast_possible_truncation,
clippy::cast_sign_loss,
clippy::cast_precision_loss,
reason = "Intentional for unit conversion, may lose precision after clamping"
)]
pub fn secs_to_millis(secs: f64) -> anyhow::Result<u64> {View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the unit of the input; if a millisecond timestamp was passed as seconds, divide by 1000 first.
- Clamp or reject timestamps above ~1.84e10 seconds before the call.
- Use u64 nanos-since-epoch semantics (Unix epoch) rather than arbitrary large durations.
Example fix
// before let ns = secs_to_nanos(ms_timestamp as f64)?; // overflow // after let ns = secs_to_nanos(ms_timestamp as f64 / 1_000.0)?;
Defensive patterns
Strategy: validation
Validate before calling
const MAX_SECS_F64: f64 = 1.8446744e10; // u64::MAX nanoseconds in seconds
if !secs.is_finite() || secs < 0.0 || secs >= MAX_SECS_F64 {
return Err(format!("seconds out of convertible range: {secs}"));
} Type guard
fn is_convertible_secs(x: f64) -> bool { x.is_finite() && x > 0.0 && x < 1.8446744e10 } Try / catch
let ns = match secs_to_nanos(secs) {
Ok(ns) => ns,
Err(e) if e.to_string().contains("out of range") => u64::MAX, // clamp, or bail
Err(e) => return Err(e),
}; Prevention
- Confirm units (seconds vs ms vs us vs ns) at every API boundary.
- UNIX epoch seconds (~1.7e9) are safe; anything above ~1.8e10 will overflow.
- Store timestamps as typed u64 nanosecond values rather than raw f64.
When it happens
Trigger: Calling secs_to_nanos with secs such that secs * 1e9 >= U64_UPPER_BOUND_F64 — i.e. roughly secs >= 1.8446744e10 seconds.
Common situations: Passing a UNIX epoch timestamp (~1.7e9 seconds) is safe, but passing a timestamp in milliseconds mistakenly as seconds (e.g. 1.7e12) overflows; misconfigured far-future expiry dates encoded as raw seconds.
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
- seconds {secs} is out of range for `u64` milliseconds
- milliseconds {millis} is out of range for `u64` nanoseconds
- microseconds {micros} is out of range for `u64` nanoseconds
- DateTime timestamp out of range for UnixNanos: {nanos}
- Negative timestamp: {unix_timestamp_ns}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2da41e7d2d7e7c3c.
Report an issue: GitHub.