nautechsystems/nautilus_trader · error
millisecond timestamp {millis} overflows when scaled to nano
Error message
millisecond timestamp {millis} overflows when scaled to nanoseconds What it means
parse_millis_to_nanos scales a millisecond timestamp to nanoseconds using checked multiplication. If millis * 1_000_000 would overflow u64 the conversion is rejected rather than silently wrapping in release builds. Real venue timestamps are nowhere near this bound, so this almost always indicates malformed input.
Source
Thrown at crates/adapters/lighter/src/common/parse.rs:173
"size precision {precision} exceeds maximum {MAX_DECIMALS}",
);
anyhow::ensure!(value.is_sign_positive(), "negative quantity `{value}`");
Quantity::from_decimal_dp(value, precision)
.map_err(|e| anyhow::anyhow!("invalid quantity `{value}` at precision {precision}: {e}"))
}
/// Converts a Unix millisecond timestamp into [`UnixNanos`].
///
/// # Errors
///
/// Returns an error if `millis * 1_000_000` would overflow `u64`. Realistic
/// venue timestamps are nowhere near this bound; the check rejects malformed
/// payloads instead of silently wrapping in release builds.
pub fn parse_millis_to_nanos(millis: u64) -> anyhow::Result<UnixNanos> {
let nanos = millis
.checked_mul(NANOSECONDS_IN_MILLISECOND)
.ok_or_else(|| {
anyhow::anyhow!("millisecond timestamp {millis} overflows when scaled to nanoseconds")
})?;
Ok(UnixNanos::from(nanos))
}
/// Converts a Unix microsecond timestamp into [`UnixNanos`].
///
/// # Errors
///
/// Returns an error if `micros * 1_000` would overflow `u64`.
pub fn parse_micros_to_nanos(micros: u64) -> anyhow::Result<UnixNanos> {
let nanos = micros.checked_mul(1_000).ok_or_else(|| {
anyhow::anyhow!("microsecond timestamp {micros} overflows when scaled to nanoseconds")
})?;
Ok(UnixNanos::from(nanos))
}
/// Converts a Unix second timestamp into [`UnixNanos`].
///View on GitHub (pinned to 18893faf8b)
Solutions
- Verify the timestamp field is actually in milliseconds; if the venue sends microseconds/nanoseconds use parse_micros_to_nanos / parse_secs_to_nanos instead.
- Inspect the raw payload for the offending value; treat it as a malformed message and drop/resynchronize.
- If intentionally probing limits, keep values below ~1.8e13 milliseconds.
Example fix
// before let ts = parse_millis_to_nanos(venue_nanos_field)?; // field is actually nanos // after let ts = UnixNanos::from(venue_nanos_field); // already nanoseconds — no scaling
Defensive patterns
Strategy: validation
Validate before calling
const MAX_MS: u64 = u64::MAX / 1_000_000; // ~1.8e13
fn millis_plausible(ms: u64) -> bool { ms < MAX_MS && ms > 1_400_000_000_000 } Type guard
fn is_millis(v: u64) -> bool { (1_400_000_000_000..u64::MAX / 1_000_000).contains(&v) } Try / catch
let ts = parse_millis_to_nanos(millis)
.or_else(|_| parse_micros_to_nanos(millis).map(|_| unreachable))
.unwrap_or_else(|_| { warn!("bad timestamp {millis}"); UnixNanos::default() }); Prevention
- Confirm timestamp units (ms vs us vs ns) per venue field before choosing the parser
- Range-check timestamps against a plausible window (e.g. 2014..2100) before conversion
- Use the checked_* based parsers; never hand-multiply timestamps into nanos
When it happens
Trigger: Calling parse_millis_to_nanos or its callers (parse_optional_millis_to_nanos, parse_trade_tick, parse_candle_bar, parse_ws_order_book_deltas, parse_ws_order_book_depth10) with a millis value greater than u64::MAX / 1_000_000 (~1.8e13 ms, year ~2262+) — e.g. a garbage or corrupted timestamp field in a venue payload.
Common situations: Corrupted websocket frames; a venue field misinterpreted (e.g. micros or nanos passed where millis expected, inflating the number); unit tests probing overflow behavior (see parse_millis_to_nanos_rejects_overflow).
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
- microsecond timestamp {micros} overflows when scaled to nano
- second timestamp {secs} overflows when scaled to nanoseconds
- Binance {field} timestamp is outside the UnixNanos range: {v
- Invalid execution time format: {time_str}
- Execution timestamp '{time_str}' is non-existent in timezone
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/82204404b25e40c4.
Report an issue: GitHub.