{"record":{"id":"e74c6f54a227ce88","repo":"nautechsystems/nautilus_trader","slug":"timestamp-overflow-for-ts","errorCode":null,"errorMessage":"Timestamp overflow for '{ts}'","messagePattern":"Timestamp overflow for '(.+?)'","errorType":"validation","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/websocket/parse.rs","lineNumber":50,"sourceCode":"use serde::Serialize;\n\nuse super::messages::{\n    PolymarketBestBidAsk, PolymarketBookLevel, PolymarketBookSnapshot, PolymarketQuote,\n    PolymarketTrade,\n};\nuse crate::common::{\n    enums::PolymarketOrderSide,\n    parse::{determine_trade_id, parse_decimal_exact},\n};\n\n/// Parses a millisecond epoch timestamp string into [`UnixNanos`].\npub fn parse_timestamp_ms(ts: &str) -> anyhow::Result<UnixNanos> {\n    let ms: u64 = ts\n        .parse()\n        .map_err(|e| anyhow::anyhow!(\"Invalid timestamp '{ts}': {e}\"))?;\n    let ns = ms\n        .checked_mul(NANOSECONDS_IN_MILLISECOND)\n        .ok_or_else(|| anyhow::anyhow!(\"Timestamp overflow for '{ts}'\"))?;\n    Ok(UnixNanos::from(ns))\n}\n\npub(crate) fn parse_price(s: &str, precision: u8) -> CorrectnessResult<Price> {\n    let value = parse_decimal_exact(s).map_err(|e| CorrectnessError::PredicateViolation {\n        message: format!(\"Invalid price '{s}': {e}\"),\n    })?;\n    Price::from_decimal_dp(value, precision)\n}\n\npub(crate) fn parse_quantity(s: &str, precision: u8) -> CorrectnessResult<Quantity> {\n    let value = parse_decimal_exact(s).map_err(|e| CorrectnessError::PredicateViolation {\n        message: format!(\"Invalid quantity '{s}': {e}\"),\n    })?;\n    Quantity::from_decimal_dp(value, precision)\n}\n\npub(crate) fn verify_book_snapshot_hash(","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/websocket/parse.rs#L32-L68","documentation":"After parsing the millisecond value as u64, parse_timestamp_ms multiplies by NANOSECONDS_IN_MILLISECOND using checked_mul. If the millisecond value is so large that the nanosecond product overflows u64, it refuses to produce a wrapped value and returns this overflow error.","triggerScenarios":"Calling parse_timestamp_ms with a millisecond value greater than u64::MAX / 1_000_000 (≈ 18,446,744,073,709 ms ≈ year 584,542,048 in epoch ms) — practically only from corrupted or malicious payloads, or a string with many digits.","commonSituations":"Fuzzed or adversarial WebSocket payloads with absurd timestamps; a unit bench test using sentinel values like u64::MAX; accidental unit confusion (nanoseconds passed where milliseconds are expected).","solutions":["Inspect the ts string in the error — an absurd value usually means a corrupted or malicious payload","Drop/skip the message rather than failing the stream for out-of-range timestamps","Ensure you pass milliseconds, not nanoseconds or microseconds (adjust conversion)","Pre-validate the magnitude: reject ms > 253_402_300_728_999 (year 9999) as obviously invalid"],"exampleFix":"// before: giant sentinel value overflows\nlet ts = parse_timestamp_ms(\"18446744073709551615\")?;\n// after: pre-validate plausible range\nlet ms: u64 = ts_str.parse()?;\nanyhow::ensure!(ms <= 4102444800000, \"timestamp far in future: {ms}\");\nlet ts = parse_timestamp_ms(ts_str)?;","handlingStrategy":"validation","validationCode":"let ms: u64 = ts_str.parse()?;\nanyhow::ensure!(ms <= 4102444800000, \"implausible timestamp: {ms}\");","typeGuard":"fn plausible_millis(raw: &str) -> bool {\n    matches!(raw.parse::<u64>(), Ok(ms) if ms <= 4102444800000)\n}","tryCatchPattern":"match parse_timestamp_ms(ts) {\n    Ok(nanos) => /* proceed */,\n    Err(e) if e.to_string().contains(\"overflow\") => {\n        log::error!(\"corrupt/giant timestamp dropped: {e}\");\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Pass milliseconds, not nanoseconds or microseconds","Sanity-bound timestamps (e.g. year 2000–9999) before conversion","Treat absurd timestamps as corrupted payloads and drop them"],"tags":["polymarket","timestamp","overflow"],"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"}