clockworklabs/SpacetimeDB · warning

Timestamp with i64 microseconds since Unix epoch overflows S

Error message

Timestamp with i64 microseconds since Unix epoch overflows SystemTime

What it means

Panic in `Timestamp::to_system_time`: converting a positive (post-epoch) `Timestamp` to `std::time::SystemTime` uses `UNIX_EPOCH.checked_add(duration).expect(...)`. Although the Timestamp itself fits i64 microseconds, the platform's `SystemTime` range may be smaller, so an in-range Timestamp can still overflow the conversion. Docs note no known platform has a smaller positive range, so in practice this signals an exotic platform or corruption.

Source

Thrown at crates/sats/src/timestamp.rs:94

                .as_micros()
                .try_into()
                .expect("Duration since Unix epoch overflows i64 microseconds"),
        )
    }

    /// Convert `self` into a [`SystemTime`] which refers to approximately the same point in time.
    ///
    /// This conversion may lose precision, as [`SystemTime`]'s prevision varies depending on platform.
    /// E.g. Unix targets have microsecond precision, but Windows only 100-microsecond precision.
    ///
    /// This conversion may panic if `self` is out of bounds for [`SystemTime`].
    /// We are not aware of any platforms for which [`SystemTime`] offers a smaller range than [`Timestamp`],
    /// but such a platform may exist.
    pub fn to_system_time(self) -> SystemTime {
        match self.to_duration_since_unix_epoch() {
            Ok(positive) => SystemTime::UNIX_EPOCH
                .checked_add(positive)
                .expect("Timestamp with i64 microseconds since Unix epoch overflows SystemTime"),
            Err(negative) => SystemTime::UNIX_EPOCH
                .checked_sub(negative)
                .expect("Timestamp with i64 microseconds before Unix epoch overflows SystemTime"),
        }
    }

    /// Convert a [`SystemTime`] into a [`Timestamp`] which refers to approximately the same point in time.
    ///
    /// This conversion may panic if `system_time` is out of bounds for [`Duration`].
    /// [`SystemTime`]'s range is larger than [`Timestamp`] on both Unix and Windows targets,
    /// so times in the far past or far future may panic.
    /// [`Timestamp`]'s range is approximately 292 years before and after the Unix epoch.
    pub fn from_system_time(system_time: SystemTime) -> Self {
        let duration = system_time
            .duration_since(SystemTime::UNIX_EPOCH)
            .expect("SystemTime predates the Unix epoch");
        Self::from_duration_since_unix_epoch(duration)
    }

View on GitHub (pinned to 6dee26c6ef)

Solutions

  1. Clamp or reject extreme Timestamp values before calling `to_system_time()` (e.g. validate year range 1970..9999).
  2. On 32-bit/exotic targets, verify `SystemTime`'s representable range and gate conversion accordingly.
  3. If the value came from untrusted input, validate the decoded micros against sane bounds at the parse boundary.
  4. Keep conversion centralized in one helper so future platform changes only need one fix.

Example fix

// before: direct conversion can overflow on narrow platforms
let st: SystemTime = ts.to_system_time();

// after: validate range before converting
fn to_st(ts: Timestamp) -> Option<SystemTime> {
    (ts.micros_since_unix_epoch().abs() < 1_000_000i64 * 60 * 60 * 24 * 365 * 1000)
        .then(|| ts.to_system_time())
}
Defensive patterns

Strategy: validation

Validate before calling

const SANITY_MICROS: i64 = 31_557_600_000_000 * 10_000; // ~10k years
fn ts_to_system_time(ts: Timestamp) -> Option<SystemTime> {
    ts.micros_since_unix_epoch().checked_abs()
        .filter(|m| *m < SANITY_MICROS)
        .and_then(|_| Some(ts.to_system_time()))
}

Prevention

When it happens

Trigger: Calling `to_system_time()` on a Timestamp whose value is near the i64-microsecond maximum (~year 296k) on a platform whose `SystemTime` cannot represent it. On mainstream 64-bit Linux/macOS/Windows this effectively cannot fire; it would require unusual targets (32-bit time_t, exotic RTOS) or a corrupted Timestamp value from deserialization.

Common situations: Cross-compiling SpacetimeDB libraries to 32-bit or embedded targets; deserializing untrusted/corrupt timestamps that decode to extreme values; test code constructing Timestamps from raw i64 microseconds near limits.

Related errors


AI-assisted analysis of clockworklabs/SpacetimeDB@6dee26c6ef (2026-08-20). Data as JSON: /api/errors/4e6d555663135fb9. Report an issue: GitHub.