vectordotdev/vector · error

shutdown_complete_tripwire for source

Error message

shutdown_complete_tripwire for source "{id}" not found in the ShutdownCoordinator

What it means

Panic from `.expect("invalid timestamp")` in `get_timestamp` (src/sources/aws_sqs/source.rs:192), converting the SQS `SentTimestamp` message-system attribute (milliseconds since epoch, as a string) into a chrono `DateTime<Utc>` via `Utc.timestamp_millis_opt`. `timestamp_millis_opt` returns None when the millisecond value is outside chrono's supported range, so the expect fires on an out-of-range or absurd SentTimestamp.

Solutions

  1. Validate the parsed millis against a plausible range (e.g. 0..=253_402_300_799_000) and return None (the function already returns Option) instead of panicking.
  2. Replace expect with `.single()?` so an invalid timestamp simply omits the timestamp field.
  3. Check the producer of the messages is sending milliseconds-since-epoch, not another unit.

Example fix

// before
Utc.timestamp_millis_opt(i64::from_str(sent_time_str).ok()?)
    .single()
    .expect("invalid timestamp")
// after
Utc.timestamp_millis_opt(i64::from_str(sent_time_str).ok()?)
    .single()
Defensive patterns

Strategy: validation

Validate before calling

fn valid_sent_timestamp(ms: i64) -> bool {
    (0..=253_402_300_799_000).contains(&ms)
}

Type guard

fn parse_sent_ts(s: &str) -> Option<DateTime<Utc>> {
    let ms = i64::from_str(s).ok()?;
    if !(0..=253_402_300_799_000).contains(&ms) { return None; }
    Utc.timestamp_millis_opt(ms).single()
}

Try / catch

// The function already returns Option — propagate instead of panicking:
Utc.timestamp_millis_opt(i64::from_str(sent_time_str).ok()?).single()

Prevention

When it happens

Trigger: The SQS message attribute `SentTimestamp` parses to an i64 (e.g. `0`, negative, or an astronomically large value) that `Utc.timestamp_millis_opt` cannot convert to a valid UTC datetime; also triggered by i64 overflow via `i64::from_str(sent_time_str)` on a 19+ digit string that fits i64 but exceeds chrono's date range.

Common situations: Test harnesses or mock SQS producers setting SentTimestamp to 0 or placeholder values; a producer bug emitting epoch-nanoseconds or epoch-microseconds instead of milliseconds; clock skew or corrupted queue attributes.

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/4e4a5e01db44ef8d. Report an issue: GitHub.

Appendix: source

Thrown at lib/vector-common/src/shutdown.rs:275

    /// has been taken over with `Self::takeover_source`).
    pub fn shutdown_source(
        &mut self,
        id: &ComponentKey,
        deadline: Instant,
    ) -> impl Future<Output = bool> + use<> {
        let (_, begin_shutdown_trigger) = self.begun_triggers.remove(id).unwrap_or_else(|| {
            panic!(
                "shutdown_begun_trigger for source \"{id}\" not found in the ShutdownCoordinator"
            )
        });
        // This is what actually triggers the source to begin shutting down.
        begin_shutdown_trigger.cancel();

        let shutdown_complete_tripwire = self
            .complete_tripwires
            .remove(id)
            .unwrap_or_else(|| {
                panic!(
                "shutdown_complete_tripwire for source \"{id}\" not found in the ShutdownCoordinator"
            )
            });
        let shutdown_force_trigger = self.force_triggers.remove(id).unwrap_or_else(|| {
            panic!(
                "shutdown_force_trigger for source \"{id}\" not found in the ShutdownCoordinator"
            )
        });
        SourceShutdownCoordinator::shutdown_source_complete(
            shutdown_complete_tripwire,
            shutdown_force_trigger,
            id.clone(),
            Some(deadline),
        )
    }

    /// Returned future will finish once all *current* sources have finished.
    #[must_use]

View on GitHub (pinned to bdb87aeaa4)