risingwavelabs/risingwave · error · InvalidParamsError
Invalid datetime: {value} {unit} is out of range
Error message
Invalid datetime: {value} {unit} is out of range What it means
ErrorKind::Timestamp is raised when a millisecond or microsecond count since the Unix epoch cannot be converted into a Timestamp: DateTime::from_timestamp_millis/micros returns None because the value is out of chrono's representable range. It is produced via InvalidParamsError::timestamp(value, unit) from Timestamp::with_millis / Timestamp::with_micros.
Source
Thrown at src/common/src/types/datetime.rs:257
fn from(interval: Interval) -> Self {
let usecs = interval.usecs_of_day();
let secs = (usecs / 1_000_000) as u32;
let nano = (usecs % 1_000_000 * 1000) as u32;
Time::from_num_seconds_from_midnight_uncheck(secs, nano)
}
}
#[derive(Copy, Clone, Debug, Error)]
enum ErrorKind {
#[error("Invalid date: days: {days}")]
Date { days: i32 },
#[error("Invalid time: secs: {secs}, nanoseconds: {nsecs}")]
Time { secs: u32, nsecs: u32 },
#[error("Invalid time: {value} {unit} is out of range for a time of day")]
TimeOfDay { value: u64, unit: &'static str },
#[error("Invalid datetime: seconds: {secs}, nanoseconds: {nsecs}")]
DateTime { secs: i64, nsecs: u32 },
#[error("Invalid datetime: {value} {unit} is out of range")]
Timestamp { value: i64, unit: &'static str },
#[error("Can't cast string to date (expected format is YYYY-MM-DD)")]
ParseDate,
#[error(
"Can't cast string to time (expected format is HH:MM:SS[.D+{{up to 6 digits}}][Z] or HH:MM)"
)]
ParseTime,
#[error(
"Can't cast string to timestamp (expected format is YYYY-MM-DD HH:MM:SS[.D+{{up to 9 digits}}] or YYYY-MM-DD HH:MM or YYYY-MM-DD or ISO 8601 format)"
)]
ParseTimestamp,
}
#[derive(Debug, Error)]
#[error(transparent)]
pub struct InvalidParamsError(#[from] ErrorKind);
impl InvalidParamsError {View on GitHub (pinned to 6469eb736d)
Solutions
- Clamp or validate the epoch value to chrono's representable range before calling with_millis/with_micros.
- Confirm the value's unit (ms vs us vs ns) matches the constructor being used.
- Treat sentinel/placeholder values (i64::MIN/MAX, 0 meaning 'unset') explicitly before conversion.
Example fix
// before
let ts = Timestamp::with_micros(raw_i64)?;
// after
let ts = if raw_i64 == i64::MAX { None } else { Some(Timestamp::with_micros(raw_i64)?) }; Defensive patterns
Strategy: validation
Validate before calling
fn can_be_timestamp_millis(ms: i64) -> bool {
DateTime::from_timestamp_millis(ms).is_some()
} Type guard
fn is_plausible_epoch_millis(ms: i64) -> bool {
(-62_167_219_200_000..=253_402_300_799_999).contains(&ms)
} Try / catch
let ts = Timestamp::with_millis(ms)
.map_err(|e| anyhow!("epoch ms {ms} out of range: {e}"))?; Prevention
- Explicitly handle sentinel values like i64::MAX before conversion.
- Confirm unit (ms/us/ns) matches the constructor used.
- Bound-check incoming epoch values at system boundaries (ingest/ETL).
When it happens
Trigger: Timestamp::with_millis(ms) or Timestamp::with_micros(us) with values beyond ~ +/-262,000 years from 1970 (out of chrono NaiveDateTime range); protobuf deserialization paths that feed a raw i64 into with_micros.
Common situations: Downstream systems sending sentinel values (e.g. i64::MAX) for 'unknown timestamp'; unit confusion where a value in nanoseconds is passed to with_micros; corrupted protobuf frames.
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
- Invalid datetime: seconds: {secs}, nanoseconds: {nsecs}
- Invalid time: {value} {unit} is out of range for a time of d
- Can't cast string to timestamp (expected format is YYYY-MM-D
- initial epoch {} greater than aligned initial epoch {}
- newly start epoch {} after update vnode bitmap not matched w
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/2cf61363fa7b68ef.
Report an issue: GitHub.