vectordotdev/vector · critical
invalid timestamp
Error message
invalid timestamp
What it means
Splunk HEC events accept a numeric `time` field. When it is a float, Vector converts to seconds+nanos and calls `Utc.timestamp_opt(...).single().expect("invalid timestamp")` (src/sources/splunk_hec/mod.rs:1042). chrono only supports roughly years -262144..+262143 (|seconds| < ~8.3e12); outside that range `timestamp_opt` returns `LocalResult::None`, `.single()` yields None, and the HEC source task panics — a single malformed request can take down the source.
Source
Thrown at src/sources/splunk_hec/mod.rs:1042
};
match parsed_time {
None => Ok(()),
Some(Some(t)) => {
if let Some(t) = t.as_u64() {
let time = parse_timestamp(t as i64).ok_or(ApiError::InvalidDataFormat {
event: self.envelopes_processed.saturating_sub(1),
})?;
self.time = Time::Provided(time);
Ok(())
} else if let Some(t) = t.as_f64() {
self.time = Time::Provided(
Utc.timestamp_opt(
t.floor() as i64,
(t.fract() * 1000.0 * 1000.0 * 1000.0) as u32,
)
.single()
.expect("invalid timestamp"),
);
Ok(())
} else {
Err(ApiError::InvalidDataFormat {
event: self.envelopes_processed.saturating_sub(1),
}
.into())
}
}
Some(None) => Err(ApiError::InvalidDataFormat {
event: self.envelopes_processed.saturating_sub(1),
}
.into()),
}
}
fn build_event(&mut self, mut json: JsonValue) -> Result<Event, Rejection> {
self.envelopes_processed += 1;View on GitHub (pinned to 3708c39b12)
Solutions
- Fix the sender: `time` must be epoch seconds (float allowed), or omit it so Splunk/Vector fills it in
- Front the HEC endpoint with a validating proxy that rejects |time| beyond ~8.3e12
- Upgrade Vector / patch the source to bound-check and return ApiError::InvalidDataFormat instead of panicking
Example fix
// before
Utc.timestamp_opt(
t.floor() as i64,
(t.fract() * 1000.0 * 1000.0 * 1000.0) as u32,
)
.single()
.expect("invalid timestamp")
// after
Utc.timestamp_opt(
t.floor() as i64,
(t.fract() * 1000.0 * 1000.0 * 1000.0) as u32,
)
.single()
.ok_or(ApiError::InvalidDataFormat {
event: self.envelopes_processed.saturating_sub(1),
})? Defensive patterns
Strategy: validation
Validate before calling
# sender-side (Python): HEC `time` must be epoch seconds within chrono's range
import math
VALID = isinstance(t, (int, float)) and math.isfinite(t) and abs(t) < 8.3e12
if not VALID:
t = time.time() # or omit the field Type guard
def valid_hec_time(t) -> bool:
return isinstance(t, (int, float)) and math.isfinite(t) and abs(t) < 8.3e12 Prevention
- Send HEC time as fractional epoch seconds only; never ms/µs/ns or YYYYMMDDHHMMSS
- Omit `time` and let the receiver stamp it when in doubt
- Place a schema-validating proxy (or Vector's own http source + remap guard) in front of exposed HEC endpoints
- Upgrade Vector once a release bounds-checks `time` instead of panicking
When it happens
Trigger: A client POSTing to /services/collector/event with `time` as nanoseconds (~1.7e18), microseconds (~1.7e15), or a formatted number like 20240101120000 (~2.0e13) — all beyond chrono's range; also `time: Infinity` (float-to-int saturates to i64::MAX, out of range).
Common situations: Apps that assume ms/µs/ns units instead of HEC's expected (fractional) epoch seconds; test harnesses posting literal YYYYMMDDHHMMSS numbers; any internet-reachable unauthenticated HEC endpoint, which turns this into a remote crash/DoS vector.
Related errors
- invalid timestamp
- invalid timestamp
- Indexer acknowledgements channel must allow at least one pen
- No timeout is configured for this source.
- Timestamp out of range
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/ea9a25ea00d9e825.
Report an issue: GitHub.