nautechsystems/nautilus_trader · error
DurationNanos overflow in from_secs
Error message
DurationNanos overflow in from_secs
What it means
`DurationNanos::from_secs` converts whole seconds (u64) into nanoseconds. It panics when `secs * 1_000_000_000` exceeds `DurationNanos::MAX`, since the result cannot be stored in the u64 nanosecond representation. The panic is deliberate: this is the const, infallible-facing constructor documented as 'Panics if the result exceeds DurationNanos::MAX'.
Source
Thrown at crates/core/src/nanos.rs:152
/// Creates a duration from a number of whole milliseconds.
///
/// # Errors
///
/// Returns an error if the result exceeds [`DurationNanos::MAX`].
pub const fn try_from_millis(millis: u64) -> Result<Self, DurationNanosOutOfRangeError> {
Self::try_from_units(millis, NANOSECONDS_IN_MILLISECOND, "milliseconds")
}
/// Creates a duration from a number of whole seconds.
///
/// # Panics
///
/// Panics if the result exceeds [`DurationNanos::MAX`].
#[must_use]
pub const fn from_secs(secs: u64) -> Self {
match Self::try_from_secs(secs) {
Ok(duration) => duration,
Err(_) => panic!("DurationNanos overflow in from_secs"),
}
}
/// Creates a duration from a number of whole seconds.
///
/// # Errors
///
/// Returns an error if the result exceeds [`DurationNanos::MAX`].
pub const fn try_from_secs(secs: u64) -> Result<Self, DurationNanosOutOfRangeError> {
Self::try_from_units(secs, NANOSECONDS_IN_SECOND, "seconds")
}
/// Creates a duration from a number of whole minutes.
///
/// # Panics
///
/// Panics if the result exceeds [`DurationNanos::MAX`].
#[must_use]View on GitHub (pinned to 18893faf8b)
Solutions
- Use `DurationNanos::try_from_secs(secs)` and handle Err explicitly.
- Bound-check the input: reject values greater than `u64::MAX / 1_000_000_000` before construction.
- Clamp to `DurationNanos::MAX` when 'as long as possible' semantics are intended.
- Fix upstream units if the config value is already in nanoseconds/milliseconds.
Example fix
// before
let dur = DurationNanos::from_secs(ttl_secs);
// after
let dur = match DurationNanos::try_from_secs(ttl_secs) {
Ok(d) => d,
Err(_) => return Err(anyhow!("ttl_secs {ttl_secs} too large for DurationNanos")),
}; Defensive patterns
Strategy: validation
Validate before calling
const MAX_FROM_SECS: u64 = u64::MAX / 1_000_000_000;
fn can_convert_secs(s: u64) -> bool { s <= MAX_FROM_SECS } Type guard
fn fits_duration_secs(s: u64) -> Option<DurationNanos> {
DurationNanos::try_from_secs(s).ok()
} Prevention
- Use try_from_secs and map Err to a domain error in fallible paths.
- Cap TTL/expiry config values to a sane maximum (e.g. 100 years) during validation.
- Avoid u64::MAX sentinels for 'never expires'; use Option<DurationNanos> instead.
When it happens
Trigger: Calling `DurationNanos::from_secs(s)` with `s > u64::MAX / 1_000_000_000` (i.e. `s >= 18_446_744_073`, about 584 years), causing the checked multiplication inside `try_from_secs` to fail and the `Err(_)` arm to panic.
Common situations: Configuration values like 'ttl_seconds' or 'expiry_seconds' set absurdly high (e.g. u64::MAX as 'forever'); converting a lifetime or lease duration to seconds then feeding it in; test code probing extreme 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
- DurationNanos overflow in from_millis
- DurationNanos overflow in from_mins
- DurationNanos overflow in from_hours
- DurationNanos overflow in from_days
- DurationNanos overflow in from_micros
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/4126c4adf2670c91.
Report an issue: GitHub.