{"record":{"id":"795ae82b97307c1e","repo":"nautechsystems/nautilus_trader","slug":"unixnanos-overflow-in-from-micros","errorCode":null,"errorMessage":"UnixNanos overflow in from_micros","messagePattern":"UnixNanos overflow in from_micros","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":464,"sourceCode":"\n    /// Creates a new [`UnixNanos`] from a signed millisecond timestamp.\n    ///\n    /// Returns `None` if `millis` is negative or the result overflows `u64`.\n    #[must_use]\n    pub const fn from_millis_checked(millis: i64) -> Option<Self> {\n        Self::from_units_checked(millis, NANOSECONDS_IN_MILLISECOND)\n    }\n\n    /// Creates a new [`UnixNanos`] from a microsecond timestamp.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result overflows `u64`.\n    #[must_use]\n    pub const fn from_micros(micros: u64) -> Self {\n        match micros.checked_mul(NANOSECONDS_IN_MICROSECOND) {\n            Some(nanos) => Self(nanos),\n            None => panic!(\"UnixNanos overflow in from_micros\"),\n        }\n    }\n\n    /// Creates a new [`UnixNanos`] from a signed microsecond timestamp.\n    ///\n    /// Returns `None` if `micros` is negative or the result overflows `u64`.\n    #[must_use]\n    pub const fn from_micros_checked(micros: i64) -> Option<Self> {\n        Self::from_units_checked(micros, NANOSECONDS_IN_MICROSECOND)\n    }\n\n    const fn from_units_checked(value: i64, nanos_per_unit: u64) -> Option<Self> {\n        if value < 0 {\n            return None;\n        }\n\n        match value.cast_unsigned().checked_mul(nanos_per_unit) {\n            Some(nanos) => Some(Self(nanos)),","sourceCodeStart":446,"sourceCodeEnd":482,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L446-L482","documentation":"`UnixNanos::from_micros` converts a microsecond timestamp to nanoseconds using `checked_mul(NANOSECONDS_IN_MICROSECOND)` and panics on u64 overflow. Overflow means the microsecond value exceeds about 18,446,744,073,709,551 microseconds since epoch, outside the representable UnixNanos range.","triggerScenarios":"Calling `UnixNanos::from_micros(u)` with `u > 18_446_744_073_709` (u64::MAX / 1e3), so checked_mul returns None and the panic fires.","commonSituations":"Unit confusion: passing nanosecond or millisecond values into from_micros; timestamps from external systems (e.g. telemetry) in different precision; sentinel max-u64 values meaning 'infinite expiry'.","solutions":["Confirm the input precision and pick the matching constructor (from_millis, from_seconds, or direct `UnixNanos::new` for nanos).","Validate `micros <= u64::MAX / 1_000` before the call.","Use a checked path (`micros.checked_mul(1_000)`) and handle None gracefully.","Clamp or reject out-of-range timestamps at the data-ingestion boundary."],"exampleFix":"// before\nlet ts = UnixNanos::from_micros(event_ts_us);\n\n// after\nlet ts = match event_ts_us.checked_mul(1_000) {\n    Some(n) => UnixNanos::new(n),\n    None => return Err(anyhow!(\"event_ts_us out of UnixNanos range\")),\n};","handlingStrategy":"validation","validationCode":"const MAX_UNIXNANOS_MICROS: u64 = u64::MAX / 1_000;\nfn valid_epoch_micros(u: u64) -> bool { u <= MAX_UNIXNANOS_MICROS }","typeGuard":"fn unix_nanos_from_micros(u: u64) -> Option<UnixNanos> {\n    u.checked_mul(1_000).map(UnixNanos::new)\n}","tryCatchPattern":null,"preventionTips":["Verify microsecond precision at the data source; telemetry often emits nanos.","Bound-check microsecond timestamps before conversion.","Fall back to the Option-returning checked path for external inputs."],"tags":["rust","panic","integer-overflow","timestamp","unix-nanos"],"backgroundTag":"value-out-of-range","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}