nautechsystems/nautilus_trader · error

seconds timestamp should fit i64

Error message

seconds timestamp should fit i64

What it means

The client order ID generator formats a UTC timestamp prefix and converts the epoch seconds (u64) to i64 for jiff's Timestamp::from_second. The expect panics when the u64 epoch second exceeds i64::MAX — the system clock is absurdly far in the future (year ~292 billion).

Source

Thrown at crates/common/src/generators/client_order_id.rs:58

            + "-".len()
            + strategy_tag.len()
            + "-".len()
    } else {
        "O".len() + DATETIME_TAG_COMPACT_LEN + trader_tag.len() + strategy_tag.len()
    }
}

/// Slow path across second boundaries: rebuilds the fixed prefix directly in the output buffer.
fn write_fixed_prefix(
    buf: &mut String,
    trader_tag: &str,
    strategy_tag: &str,
    use_hyphens: bool,
    epoch_second: u64,
) {
    let now_utc = Offset::UTC.to_datetime(
        Timestamp::from_second(
            i64::try_from(epoch_second).expect("seconds timestamp should fit i64"),
        )
        .expect("seconds timestamp should be within valid range"),
    );

    buf.clear();

    if use_hyphens {
        write!(
            buf,
            "O-{:04}{:02}{:02}-{:02}{:02}{:02}-{trader_tag}-{strategy_tag}-",
            now_utc.year(),
            now_utc.month(),
            now_utc.day(),
            now_utc.hour(),
            now_utc.minute(),
            now_utc.second(),
        )
        .expect("writing to String should not fail");

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the source of the bogus timestamp (system clock or mocked clock)
  2. Clamp/saturate the epoch second to i64 range before formatting: i64::try_from(sec).unwrap_or(i64::MAX)
  3. Add an upstream validity check (epoch_second within a sane range) before generating IDs
  4. If this comes from a test, use a realistic timestamp in the mock clock

Example fix

// before
let now_utc = Offset::UTC.to_datetime(
    Timestamp::from_second(
        i64::try_from(epoch_second).expect("seconds timestamp should fit i64"),
    )...
// after
let sec = i64::try_from(epoch_second).unwrap_or(i64::MAX);
Defensive patterns

Strategy: validation

Validate before calling

fn plausible_epoch_second(sec: u64) -> bool {
    // between 2000-01-01 and year 2100
    (946_684_800..=4_102_444_800).contains(&sec)
}

Try / catch

// Pre-check before generating IDs from a clock value
let sec = now_sec();
assert!(plausible_epoch_second(sec), "implausible clock value: {sec}");

Prevention

When it happens

Trigger: Calling write_fixed_prefix (via refresh_fixed_prefix) with epoch_second larger than i64::MAX, which only occurs if SystemTime/clock supplies an astronomically large value.

Common situations: Corrupt or mocked clocks returning huge values; fuzzing or property tests feeding u64::MAX timestamps; integer-overflow bugs upstream.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/4cba3e62645e3d92. Report an issue: GitHub.