nautechsystems/nautilus_trader · error
DurationNanos overflow in from_days
Error message
DurationNanos overflow in from_days
What it means
`DurationNanos::from_days` converts whole days (u64) to nanoseconds and panics if `days * 86_400 * 1_000_000_000` exceeds `DurationNanos::MAX`. It mirrors the other panicking constructors: the fallible logic lives in `try_from_days`, and overflow is escalated to a panic for this const API.
Source
Thrown at crates/core/src/nanos.rs:218
/// Creates a duration from a number of whole hours.
///
/// # Errors
///
/// Returns an error if the result exceeds [`DurationNanos::MAX`].
pub const fn try_from_hours(hours: u64) -> Result<Self, DurationNanosOutOfRangeError> {
Self::try_from_units(hours, SECONDS_IN_HOUR * NANOSECONDS_IN_SECOND, "hours")
}
/// Creates a duration from a number of whole days.
///
/// # Panics
///
/// Panics if the result exceeds [`DurationNanos::MAX`].
#[must_use]
pub const fn from_days(days: u64) -> Self {
match Self::try_from_days(days) {
Ok(duration) => duration,
Err(_) => panic!("DurationNanos overflow in from_days"),
}
}
/// Creates a duration from a number of whole days.
///
/// # Errors
///
/// Returns an error if the result exceeds [`DurationNanos::MAX`].
pub const fn try_from_days(days: u64) -> Result<Self, DurationNanosOutOfRangeError> {
Self::try_from_units(days, NANOSECONDS_IN_DAY, "days")
}
const fn try_from_units(
value: u64,
nanos_per_unit: u64,
unit: &'static str,
) -> Result<Self, DurationNanosOutOfRangeError> {
match value.checked_mul(nanos_per_unit) {View on GitHub (pinned to 18893faf8b)
Solutions
- Use `DurationNanos::try_from_days(days)` and handle Err.
- Validate `days <= u64::MAX / 86_400_000_000_000` before calling.
- Clamp to `DurationNanos::MAX` when 'maximum representable' is the intent.
- Correct the upstream unit (e.g. value is already in hours).
Example fix
// before
let dur = DurationNanos::from_days(retention_days);
// after
let dur = DurationNanos::try_from_days(retention_days)
.unwrap_or(DurationNanos::MAX); // saturate 'permanent' retention Defensive patterns
Strategy: validation
Validate before calling
const MAX_FROM_DAYS: u64 = u64::MAX / 86_400_000_000_000;
fn can_convert_days(d: u64) -> bool { d <= MAX_FROM_DAYS } Type guard
fn fits_duration_days(d: u64) -> Option<DurationNanos> {
DurationNanos::try_from_days(d).ok()
} Prevention
- Reject day values above ~213 million during input validation.
- Use try_from_days for user/config supplied retention windows.
- Replace u64::MAX 'permanent' sentinels with Option or a named constant.
When it happens
Trigger: Calling `DurationNanos::from_days(d)` with `d > u64::MAX / 86_400_000_000_000` (i.e. `d >= 213_503_982` days, about 584 years), causing `try_from_days` to return Err and the panic to fire.
Common situations: Sentinel values like u64::MAX days for 'permanent' retention; misconfigured units (hours/months passed as days); property-based tests over 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
- DurationNanos overflow in from_millis
- DurationNanos overflow in from_secs
- DurationNanos overflow in from_mins
- DurationNanos overflow in from_hours
- DurationNanos overflow in from_micros
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/2b0e638f10000b38.
Report an issue: GitHub.