nautechsystems/nautilus_trader · error

DurationNanos overflow in from_micros

Error message

DurationNanos overflow in from_micros

What it means

`DurationNanos::from_micros` is the panicking constructor for durations from whole microseconds; since `DurationNanos` is a `u64` nanosecond count, a microsecond value above `u64::MAX / 1_000` (~18446744073709551 micros, about 584,000 years) overflows and panics with this message. The library pairs every panicking constructor with a `try_from_micros` variant returning `DurationNanosOutOfRangeError` for callers that want fallible handling. In practice this only fires with extreme or bogus (unvalidated/huge) u64 inputs.

Source

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

    /// The maximum duration representable by this type.
    pub const MAX: Self = Self(u64::MAX);

    /// Creates a duration from an exact nanosecond count.
    #[must_use]
    pub const fn new(nanos: u64) -> Self {
        Self(nanos)
    }

    /// Creates a duration from a number of whole microseconds.
    ///
    /// # Panics
    ///
    /// Panics if the result exceeds [`DurationNanos::MAX`].
    #[must_use]
    pub const fn from_micros(micros: u64) -> Self {
        match Self::try_from_micros(micros) {
            Ok(duration) => duration,
            Err(_) => panic!("DurationNanos overflow in from_micros"),
        }
    }

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

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

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Use the fallible `DurationNanos::try_from_micros(micros)` and handle `DurationNanosOutOfRangeError`.
  2. Check `micros <= u64::MAX / 1_000` (18446744073709551) before calling `from_micros`.
  3. Audit the value's unit — the input may actually be seconds/millis being multiplied into micros twice.
  4. Validate config/FFI duration values against a sane upper bound before conversion.

Example fix

// before
let duration = DurationNanos::from_micros(config_micros); // panics on huge values
// after
let duration = DurationNanos::try_from_micros(config_micros)
    .map_err(|e| anyhow!("invalid duration config: {e}"))?;
Defensive patterns

Strategy: try-catch

Validate before calling

const NANOS_PER_MICRO: u64 = 1_000;
fn micros_in_range(micros: u64) -> bool {
    micros <= u64::MAX / NANOS_PER_MICRO // 18446744073709551
}

Type guard

fn fits_duration_nanos(micros: u64) -> bool {
    micros.checked_mul(1_000).is_some()
}

Try / catch

// Rust panics are not catchable; use the fallible constructor
let duration = match DurationNanos::try_from_micros(micros) {
    Ok(d) => d,
    Err(e) => return Err(anyhow!("duration out of range: {e}")),
};

Prevention

When it happens

Trigger: Calling `DurationNanos::from_micros(micros)` with `micros > u64::MAX / NANOSECONDS_IN_MICROSECOND` (18446744073709551); e.g. converting a raw unvalidated u64 from config, FFI, or a wire protocol.

Common situations: Passing seconds/milliseconds accidentally as microseconds (unit confusion multiplying by 1000 too many times); unvalidated config values like `u64::MAX` sentinels used as durations; FFI or deserialized data with corrupted duration fields.

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/c30dc0ac36a7d118. Report an issue: GitHub.