vectordotdev/vector · error
Failed type coercion, {self:?} is not a metric
Error message
Failed type coercion, {self:?} is not a metric What it means
`Event::as_metric` (lib/vector-core/src/event/mod.rs:172-181) borrows the event as `&Metric` and panics with a debug dump when the event is `Event::Log` or `Event::Trace`. Metric-oriented components (aggregations, metric sinks) rely on this precondition; code that cannot guarantee the variant must check first, since no fallible borrow twin exists for metrics in this impl.
Source
Thrown at lib/vector-core/src/event/mod.rs:180
/// Return self as a `LogEvent` if possible
///
/// If the event is a `LogEvent`, then `Some(&log_event)` is returned, otherwise `None`.
pub fn maybe_as_log(&self) -> Option<&LogEvent> {
match self {
Event::Log(log) => Some(log),
_ => None,
}
}
/// Return self as a `Metric`
///
/// # Panics
///
/// This function panics if self is anything other than an `Event::Metric`.
pub fn as_metric(&self) -> &Metric {
match self {
Event::Metric(metric) => metric,
_ => panic!("Failed type coercion, {self:?} is not a metric"),
}
}
/// Return self as a mutable `Metric`
///
/// # Panics
///
/// This function panics if self is anything other than an `Event::Metric`.
pub fn as_mut_metric(&mut self) -> &mut Metric {
match self {
Event::Metric(metric) => metric,
_ => panic!("Failed type coercion, {self:?} is not a metric"),
}
}
/// Coerces self into `Metric`
///
/// # PanicsView on GitHub (pinned to 3708c39b12)
Solutions
- Guard with `matches!(event, Event::Metric(_))` before calling `as_metric`.
- Branch on the variant and route non-metric events to their proper handler or drop them with an emitted error.
- Split the topology so metrics sources and log sources feed separate pipelines.
Example fix
// before
let metric = event.as_metric(); // panics on Log/Trace
// after
match &event {
Event::Metric(metric) => aggregate(metric),
other => emit!(UnexpectedEvent { event: &other }),
} Defensive patterns
Strategy: type-guard
Validate before calling
if matches!(event, Event::Metric(_)) {
let metric = event.as_metric();
} Type guard
fn is_metric_event(e: &Event) -> bool { matches!(e, Event::Metric(_)) } Prevention
- Guard as_metric() with a variant check in any generic event loop.
- Keep metric-only components on metrics-only pipeline branches.
- Include log-event fixtures in metric component tests to catch unguarded coercions.
When it happens
Trigger: Calling `event.as_metric()` on a log event, e.g. a metrics aggregation transform or a Prometheus-style sink receiving logs because sources and sinks were wired into the same stream; trace events from an OTLP source hitting the same call.
Common situations: A pipeline where `stdin`/file/http log sources share a topology branch with a metrics sink; custom metric transforms reusing generic event loops; fixtures that build log events but exercise metric-only code paths.
Related errors
- Failed type coercion, {self:?} is not a metric reference
- Failed type coercion, {self:?} is not a log event
- Failed type coercion, {self:?} is not a log 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/6da7d3140264f931.
Report an issue: GitHub.