nautechsystems/nautilus_trader · error

DurationNanos overflow in from_mins

Error message

DurationNanos overflow in from_mins

What it means

`DurationNanos::from_mins` converts whole minutes (u64) to nanoseconds and panics if the product `mins * 60 * 1_000_000_000` exceeds `DurationNanos::MAX`. It is the panicking front-end of `try_from_mins`, kept `const` so it can be used in const contexts; overflow is treated as a programmer error.

Source

Thrown at crates/core/src/nanos.rs:174

    /// 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]
    pub const fn from_mins(mins: u64) -> Self {
        match Self::try_from_mins(mins) {
            Ok(duration) => duration,
            Err(_) => panic!("DurationNanos overflow in from_mins"),
        }
    }

    /// Creates a duration from a number of whole minutes.
    ///
    /// # Errors
    ///
    /// Returns an error if the result exceeds [`DurationNanos::MAX`].
    pub const fn try_from_mins(mins: u64) -> Result<Self, DurationNanosOutOfRangeError> {
        Self::try_from_units(mins, NANOSECONDS_IN_MINUTE, "minutes")
    }

    /// Creates a duration from a number of whole hours.
    ///
    /// # Panics
    ///
    /// Panics if the result exceeds [`DurationNanos::MAX`].
    #[must_use]

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Switch to `DurationNanos::try_from_mins(mins)` and handle the error.
  2. Validate `mins <= u64::MAX / 60_000_000_000` before the call.
  3. Clamp to `DurationNanos::MAX` if saturation is acceptable.
  4. Correct the unit of the configured value.

Example fix

// before
let dur = DurationNanos::from_mins(lease_mins);

// after
const MAX_MINS: u64 = u64::MAX / 60_000_000_000;
let dur = if lease_mins > MAX_MINS {
    DurationNanos::MAX
} else {
    DurationNanos::from_mins(lease_mins)
};
Defensive patterns

Strategy: validation

Validate before calling

const MAX_FROM_MINS: u64 = u64::MAX / 60_000_000_000;
fn can_convert_mins(m: u64) -> bool { m <= MAX_FROM_MINS }

Type guard

fn fits_duration_mins(m: u64) -> Option<DurationNanos> {
    DurationNanos::try_from_mins(m).ok()
}

Prevention

When it happens

Trigger: Calling `DurationNanos::from_mins(m)` with `m > u64::MAX / 60_000_000_000` (i.e. `m >= 307_445_734` minutes, about 584 years), making `try_from_mins` return Err and the panic arm fire.

Common situations: Encoding 'unlimited' or 'forever' as u64::MAX in config; accidental unit confusion (value is actually seconds or nanos); synthetic/fuzz inputs spanning the full u64 range.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/76067ac9e45c895b. Report an issue: GitHub.