nautechsystems/nautilus_trader · error
millisecond timestamp overflowed
Error message
millisecond timestamp overflowed
What it means
parse_millis_i64 multiplies the millisecond value by 1,000,000 to obtain nanoseconds using checked arithmetic on u64. If the resulting nanosecond value exceeds u64 range, this overflow error is thrown.
Solutions
- Log the raw value and verify its actual time unit against Bybit's API docs
- Convert with the correct unit multiplier if the field is actually microseconds/nanoseconds
- Add an upper-bound sanity check (e.g. reject timestamps far in the future) before conversion
Example fix
// before: assumes milliseconds, overflows on microsecond input let ts = parse_millis_i64(raw.ts, "ts")?; // after: correct unit for microsecond fields let ts = parse_micros_i64(raw.ts, "ts")?;
Defensive patterns
Strategy: validation
Validate before calling
def plausible_millis(v: int) -> bool:
return 0 <= v <= 4_102_444_800_000 # up to year 2100 Type guard
def is_plausible_timestamp(v) -> bool:
return isinstance(v, int) and 0 <= v <= 4_102_444_800_000 Try / catch
match parse_millis_i64(raw.ts, "ts") {
Err(e) if e.to_string().contains("overflowed") => { log_unit_mismatch(raw.ts); skip },
other => other?,
} Prevention
- Bound-check timestamps against a sane wall-clock window before conversion
- Confirm the time unit (ms vs us vs ns) after any Bybit API change
- Add fuzz/property tests with extreme timestamp values
When it happens
Trigger: A WebSocket payload (orderbook, trade tick, quote) carrying a millisecond timestamp larger than u64::MAX/1e6 (~1.8e13 ms, year ~539000) passed to parse_millis_i64.
Common situations: Upstream sending microseconds/nanoseconds mislabeled as milliseconds; unit-encoding schema changes; fabricated or fuzzed payloads with absurd timestamps.
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
- must be non-negative, was
- funding_interval_hour out of bounds
- Cannot take ownership - other references exist
- Missing server timestamp (us_out) in response
- negative candle timestamp
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/1e153b26027e8250.
Report an issue: GitHub.
Appendix: source
Thrown at crates/adapters/bybit/src/websocket/parse.rs:680
rho: 0.0, // Bybit doesn't provide rho
},
mark_iv: Some(mark_iv),
bid_iv: Some(bid_iv),
ask_iv: Some(ask_iv),
underlying_price: Some(underlying_price),
open_interest: Some(open_interest),
ts_event,
ts_init,
})
}
pub(crate) fn parse_millis_i64(value: i64, field: &str) -> anyhow::Result<UnixNanos> {
if value < 0 {
Err(anyhow::anyhow!("{field} must be non-negative, was {value}"))
} else {
let nanos = (value as u64)
.checked_mul(NANOSECONDS_IN_MILLISECOND)
.ok_or_else(|| anyhow::anyhow!("millisecond timestamp overflowed"))?;
Ok(UnixNanos::from(nanos))
}
}
/// Parses a WebSocket kline payload into a [`Bar`].
///
/// # Errors
///
/// Returns an error if price or volume fields cannot be parsed or if the bar cannot be constructed.
pub fn parse_ws_kline_bar(
kline: &BybitWsKline,
instrument: &InstrumentAny,
bar_type: BarType,
timestamp_on_close: bool,
ts_init: UnixNanos,
) -> anyhow::Result<Bar> {
let price_precision = instrument.price_precision();
let size_precision = instrument.size_precision();View on GitHub (pinned to 18893faf8b)