vectordotdev/vector · error
Failed type coercion, {self:?} is not a log reference
Error message
Failed type coercion, {self:?} is not a log reference What it means
`EventRef<'a>` is a borrowed, clone-free view over an `Event` (Log/Metric/Trace reference variants) used to avoid allocations on hot paths. `EventRef::as_log` (lib/vector-core/src/event/ref.rs:26-32) unwraps only the `Log` variant and panics with a debug dump otherwise, per its `# Panics` doc. `into_log` on the same type additionally clones the borrowed log event.
Source
Thrown at lib/vector-core/src/event/ref.rs:28
pub enum EventRef<'a> {
/// Reference to a `LogEvent`
Log(&'a LogEvent),
/// Reference to a `Metric`
Metric(&'a Metric),
/// Reference to a `TraceEvent`
Trace(&'a TraceEvent),
}
impl<'a> EventRef<'a> {
/// Extract the `LogEvent` reference in this.
///
/// # Panics
///
/// This will panic if this is not a `LogEvent` reference.
pub fn as_log(self) -> &'a LogEvent {
match self {
Self::Log(log) => log,
_ => panic!("Failed type coercion, {self:?} is not a log reference"),
}
}
/// Convert this reference into a new `LogEvent` by cloning.
///
/// # Panics
///
/// This will panic if this is not a `LogEvent` reference.
pub fn into_log(self) -> LogEvent {
match self {
Self::Log(log) => log.clone(),
_ => panic!("Failed type coercion, {self:?} is not a log reference"),
}
}
/// Extract the `Metric` reference in this.
///
/// # PanicsView on GitHub (pinned to 3708c39b12)
Solutions
- Match on the `EventRef` variant and only call `as_log` in the `Self::Log` arm.
- Skip or emit an internal error event for non-log variants instead of coercing.
- Keep log-only consumers on a routed branch that only ever emits log events.
Example fix
// before
let log = event_ref.as_log(); // panics for Metric/Trace refs
// after
match event_ref {
EventRef::Log(log) => forward(log),
EventRef::Metric(_) | EventRef::Trace(_) => emit!(WrongSignalType),
} Defensive patterns
Strategy: type-guard
Validate before calling
if let EventRef::Log(_) = event_ref {
let log = event_ref.as_log();
} Type guard
fn is_log_ref(r: &EventRef<'_>) -> bool { matches!(r, EventRef::Log(_)) } Prevention
- Match on the EventRef variant in fan-out code instead of calling as_log() directly.
- When porting owned-Event code to EventRef, carry over the variant checks that used try_into_log.
- Skip non-log refs with an emitted diagnostic so mixed pipelines degrade gracefully.
When it happens
Trigger: Calling `event_ref.as_log()` (or `event_ref.into_log()`) on an `EventRef::Metric`/`EventRef::Trace` — e.g. fan-out code that iterates pipeline outputs as `EventRef`s and forwards each to a log-only consumer such as a log sink acknowledgement or serializer path.
Common situations: Custom sinks or middleware consuming `Vec<EventRef>` from a topology output where metrics/traces share the stream; refactoring owned-`Event` code (which used `try_into_log`) to the zero-copy `EventRef` API and dropping the variant check in the process.
Related errors
- Failed type coercion, {self:?} is not a log event
- Failed type coercion, {self:?} is not a metric
- Failed type coercion, {self:?} is not a metric reference
- Failed type coercion, {self:?} is not a trace event
- Failed type coercion, {self:?} is not a Sink
AI-assisted analysis of vectordotdev/vector@3708c39b12 (2026-08-20).
Data as JSON: /api/errors/55bbfae57aef315d.
Report an issue: GitHub.