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

  1. Use a realistic `allowed_lateness_ms` value
  2. Ensure `Aggregate::new` validates `allowed_lateness_ms <= i64::MAX` and errors at config load
  3. Run `vector validate` on the config
  4. 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

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


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)