vectordotdev/vector · error

Failed type coercion, {self:?} is not a trace event

Error message

Failed type coercion, {self:?} is not a trace event

What it means

`Event::as_trace` (lib/vector-core/src/event/mod.rs:218-228) borrows the event as `&TraceEvent` and panics with a debug dump when it is `Event::Log` or `Event::Metric`. Trace-specific components (OTLP trace sinks, span processors) assume this precondition; the `# Panics` doc on the method states it, and there is no fallible borrow twin in this impl block.

Source

Thrown at lib/vector-core/src/event/mod.rs:226

    /// Fallibly coerces self into a `Metric`
    ///
    /// If the event is a `Metric`, then `Some(metric)` is returned, otherwise `None`.
    pub fn try_into_metric(self) -> Option<Metric> {
        match self {
            Event::Metric(metric) => Some(metric),
            _ => None,
        }
    }

    /// Return self as a `TraceEvent`
    ///
    /// # Panics
    ///
    /// This function panics if self is anything other than an `Event::Trace`.
    pub fn as_trace(&self) -> &TraceEvent {
        match self {
            Event::Trace(trace) => trace,
            _ => panic!("Failed type coercion, {self:?} is not a trace event"),
        }
    }

    /// Return self as a mutable `TraceEvent`
    ///
    /// # Panics
    ///
    /// This function panics if self is anything other than an `Event::Trace`.
    pub fn as_mut_trace(&mut self) -> &mut TraceEvent {
        match self {
            Event::Trace(trace) => trace,
            _ => panic!("Failed type coercion, {self:?} is not a trace event"),
        }
    }

    /// Coerces self into a `TraceEvent`
    ///
    /// # Panics

View on GitHub (pinned to 3708c39b12)

Solutions

  1. Check the variant first: `if matches!(event, Event::Trace(_))` before `as_trace`.
  2. Match on the enum and dispatch each variant to its own handler, emitting an internal error for unexpected ones.
  3. Keep trace pipelines separate (or route with a filter transform) so trace sinks only receive `Event::Trace`.

Example fix

// before
let trace = event.as_trace(); // panics on Log/Metric

// after
match &event {
    Event::Trace(trace) => export_spans(trace),
    other => emit!(UnexpectedEventForTraceSink { event: other }),
}
Defensive patterns

Strategy: type-guard

Validate before calling

if matches!(event, Event::Trace(_)) {
    let trace = event.as_trace();
}

Type guard

fn is_trace_event(e: &Event) -> bool { matches!(e, Event::Trace(_)) }

Prevention

When it happens

Trigger: Calling `event.as_trace()` on a log event from a file/http source or a metric from a prometheus source — e.g. a trace-export sink attached to a pipeline that also carries logs, or generic event-loop code reused across pipelines.

Common situations: Enabling the trace (`opentelemetry`) feature and wiring OTLP sources into shared pipelines; custom telemetry exporters that process every event through trace-specific code; fixtures with log events run against trace tests.

Related errors


AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20). Data as JSON: /api/errors/0d09a3e86e1867c5. Report an issue: GitHub.