{"record":{"id":"b6024abba6e41389","repo":"nautechsystems/nautilus_trader","slug":"unixnanos-overflow-in-from-seconds","errorCode":null,"errorMessage":"UnixNanos overflow in from_seconds","messagePattern":"UnixNanos overflow in from_seconds","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/core/src/nanos.rs","lineNumber":430,"sourceCode":"        self.0 / NANOSECONDS_IN_MILLISECOND\n    }\n\n    /// Returns the timestamp as microseconds, truncating sub-microsecond precision.\n    #[must_use]\n    pub const fn as_micros(&self) -> u64 {\n        self.0 / NANOSECONDS_IN_MICROSECOND\n    }\n\n    /// Creates a new [`UnixNanos`] from a second timestamp.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result overflows `u64`.\n    #[must_use]\n    pub const fn from_seconds(seconds: u64) -> Self {\n        match seconds.checked_mul(NANOSECONDS_IN_SECOND) {\n            Some(nanos) => Self(nanos),\n            None => panic!(\"UnixNanos overflow in from_seconds\"),\n        }\n    }\n\n    /// Creates a new [`UnixNanos`] from a millisecond timestamp.\n    ///\n    /// # Panics\n    ///\n    /// Panics if the result overflows `u64`.\n    #[must_use]\n    pub const fn from_millis(millis: u64) -> Self {\n        match millis.checked_mul(NANOSECONDS_IN_MILLISECOND) {\n            Some(nanos) => Self(nanos),\n            None => panic!(\"UnixNanos overflow in from_millis\"),\n        }\n    }\n\n    /// Creates a new [`UnixNanos`] from a signed millisecond timestamp.\n    ///","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/core/src/nanos.rs#L412-L448","documentation":"`UnixNanos::from_seconds` converts a Unix timestamp in whole seconds to nanoseconds by multiplying with `NANOSECONDS_IN_SECOND` (1e9) using `checked_mul`. If the product overflows u64, the constructor panics, since a UnixNanos timestamp cannot exceed `u64::MAX` nanoseconds (year 2554). The library throws it to fail fast rather than silently wrapping the timestamp.","triggerScenarios":"Calling `UnixNanos::from_seconds(s)` with `s > 18_446_744_073` (u64::MAX / 1e9, i.e. timestamps beyond roughly year 2554), so `checked_mul` returns None and the panic arm executes.","commonSituations":"Parsing epoch seconds from a config/env var where someone entered nanoseconds or milliseconds by mistake; sentinel u64::MAX used for 'no expiry'; deserializing timestamps from external data with wrong units.","solutions":["Verify the value is truly in seconds; if it is in milliseconds use `from_millis`, if nanoseconds use `UnixNanos::new`/`from_raw`.","Guard the input: reject values greater than `u64::MAX / 1_000_000_000` before the call.","Use a checked/clamped path: compute `seconds.checked_mul(1_000_000_000)` yourself and handle None.","Sanity-check timestamps against a plausible range (e.g. 0..=year 2200) at config load time."],"exampleFix":"// before\nlet ts = UnixNanos::from_seconds(expiry); // may be millis!\n\n// after\nlet ts = if expiry > 18_446_744_073 {\n    UnixNanos::from_millis(expiry) // value was actually milliseconds\n} else {\n    UnixNanos::from_seconds(expiry)\n};","handlingStrategy":"validation","validationCode":"const MAX_UNIXNANOS_SECS: u64 = u64::MAX / 1_000_000_000;\nfn valid_epoch_seconds(s: u64) -> bool { s <= MAX_UNIXNANOS_SECS }","typeGuard":"fn unix_nanos_from_seconds(s: u64) -> Option<UnixNanos> {\n    s.checked_mul(1_000_000_000).map(UnixNanos::new)\n}","tryCatchPattern":null,"preventionTips":["Confirm the unit of every timestamp field; seconds vs millis vs nanos is the top cause of overflow.","Range-check timestamps at ingestion (e.g. must be <= year 2200).","Never pass u64::MAX as a sentinel expiry; use Option<UnixNanos>."],"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-14T05:17:10.506Z"}