vectordotdev/vector · error
allowed_lateness_ms validated to fit in i64 in…
Error message
allowed_lateness_ms validated to fit in i64 in Aggregate::new
What it means
`is_past_bucket_cutoff` also converts `allowed_lateness_ms` (u64) to i64, expecting it fits and citing validation in `Aggregate::new`. An over-large `allowed_lateness_ms` panics here while computing the lateness grace period.
Solutions
- Use a realistic `allowed_lateness_ms` value
- Ensure `Aggregate::new` validates `allowed_lateness_ms <= i64::MAX` and errors at config load
- Run `vector validate` on the config
- File a bug if valid configs trigger the panic
Defensive patterns
Strategy: validation
Validate before calling
if cfg.event_time.allowed_lateness_ms > i64::MAX as u64 {
return Err("allowed_lateness_ms too large".into());
} Prevention
- Use practical lateness bounds (minutes/hours)
- Validate allowed_lateness_ms fits i64 at config load
- Test constructor validation with boundary values
- Run `vector validate` pre-deploy
When it happens
Trigger: `record_event_time` → `is_past_bucket_cutoff` on an Aggregate whose configured `allowed_lateness_ms` exceeds `i64::MAX` without constructor validation.
Common situations: Extremely large lateness values in hand-written config; forks/tests constructing Aggregate without running the constructor's range checks.
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
- interval_ms validated to fit in i64 in Aggregate::new
- max_future_ms validated to fit in i64 in Aggregate::new
- event-time path requires AggregateConfig.event_time
- output for default port required for task transforms
- a record with a next ID must have an event count
AI-assisted analysis of vectordotdev/vector@bdb87aeaa4 (2026-09-16).
Data as JSON: /api/errors/5e1f43aba291f2e8.
Report an issue: GitHub.
Appendix: source
Thrown at src/transforms/aggregate/event_time.rs:149
/// closed unconditionally and late events for it are dropped.
const fn was_bucket_flushed(&self, bucket_key: BucketKey) -> bool {
if let Some(watermark) = self.watermark {
bucket_key < watermark
} else {
false
}
}
/// Returns `true` when `now_ms` is at or past the end of `bucket_key`'s
/// window plus `allowed_lateness_ms` — the same predicate used to decide
/// flush eligibility in `flush_event_time_buckets`. Recording must reject
/// events once this cutoff passes even if the periodic flush tick has not
/// run yet, so strict lateness is not weakened by a long flush interval.
pub(crate) fn is_past_bucket_cutoff(&self, bucket_key: BucketKey, now_ms: i64) -> bool {
let interval_ms = i64::try_from(self.config.interval_ms)
.expect("interval_ms validated to fit in i64 in Aggregate::new");
let grace_ms = i64::try_from(self.event_time().allowed_lateness_ms)
.expect("allowed_lateness_ms validated to fit in i64 in Aggregate::new");
now_ms
>= bucket_key
.saturating_add(interval_ms)
.saturating_add(grace_ms)
}
/// Records an event-time event into the appropriate bucket.
///
/// Callers must reject incompatible events via `will_be_stored` before
/// calling this function so stray events never allocate buckets.
fn record_into_bucket(
&mut self,
bucket_key: BucketKey,
series: MetricSeries,
data: MetricData,
metadata: EventMetadata,
) {
let mode = self.config.mode;
View on GitHub (pinned to bdb87aeaa4)