vectordotdev/vector · error
not implemented
Error message
not implemented
What it means
The Protobuf serializer in Vector's codecs maps Log and Trace events onto a user-supplied message descriptor (from protobuf.desc_file + protobuf.message_type), but there is no generic protobuf mapping for Metric events, so the Encoder<Event> impl hits unimplemented!() on the Event::Metric arm (lib/codecs/src/encoding/format/protobuf.rs:124). unimplemented!() panics with 'not implemented', which crashes the Vector process (or the encoding task) the first time a metric reaches the sink. It is a deliberate gap: an arbitrary .proto descriptor cannot describe Vector's metric model, unlike the JSON codec which serializes any event type.
Source
Thrown at lib/codecs/src/encoding/format/protobuf.rs:124
options: options.clone(),
})
}
/// Get a description of the message type used in serialization.
pub fn descriptor_proto(&self) -> &prost_reflect::prost_types::DescriptorProto {
self.message_descriptor.descriptor_proto()
}
}
impl Encoder<Event> for ProtobufSerializer {
type Error = vector_common::Error;
fn encode(&mut self, event: Event, buffer: &mut BytesMut) -> Result<(), Self::Error> {
let message = match event {
Event::Log(log) => {
encode_message(&self.message_descriptor, log.into_parts().0, &self.options)
}
Event::Metric(_) => unimplemented!(),
Event::Trace(trace) => encode_message(
&self.message_descriptor,
Value::Object(trace.into_parts().0),
&self.options,
),
}?;
message.encode(buffer).map_err(Into::into)
}
}
View on GitHub (pinned to 711f03abce)
Solutions
- Add a route/filter transform (VRL: `type == "metric"`) so only log events reach the protobuf-encoded sink, and send metrics to a second sink with a metric-capable codec.
- If metrics must go through the same sink, convert them to logs first with a remap transform (e.g. encode the metric with .encode_json) before the protobuf encoder.
- Use a codec that supports Event::Metric for the metrics sink (json, native_json, text, or a metrics-aware sink protocol) instead of protobuf.
- Longer term: contribute an Event::Metric arm to ProtobufSerializer in lib/codecs/src/encoding/format/protobuf.rs (e.g. a canonical metrics descriptor), since the omission is intentional, not a bug.
Example fix
# vector.toml — before: metrics and logs share a protobuf sink (panics on first metric) [sinks.out] type = "console" inputs = ["internal_metrics", "my_log_source"] [sinks.out.encoding] codec = "protobuf" [sinks.out.encoding.protobuf] desc_file = "./protos/event.desc" message_type = "log.Event" # after: route by event type, metrics use a metric-capable codec [transforms.split] type = "route" inputs = ["internal_metrics", "my_log_source"] route.logs = 'type == "log"' route.metrics = 'type == "metric"' [sinks.out] type = "console" inputs = ["split.logs"] [sinks.out.encoding] codec = "protobuf" [sinks.out.encoding.protobuf] desc_file = "./protos/event.desc" message_type = "log.Event" [sinks.metrics_out] type = "console" inputs = ["split.metrics"] [sinks.metrics_out.encoding] codec = "json"
Defensive patterns
Strategy: validation
Validate before calling
# Rust API users: never hand Event::Metric to the protobuf serializer
if matches!(event, Event::Metric(_)) {
return route_to_metric_sink(event); // codec supports only Log and Trace
}
serializer.encode(event, &mut buffer)?;
# Config users: assert before deploy that every protobuf sink only receives logs
# with a route transform: route.logs = 'type == "log"' (or 'type != "metric"') Type guard
fn protobuf_encodable(event: &Event) -> bool {
!matches!(event, Event::Metric(_)) // Log and Trace arms are implemented
} Prevention
- Whenever a sink uses encoding.codec = "protobuf", immediately add a route/filter that excludes type == "metric" events.
- Treat codec changes as event-type contract changes: re-check every input to that sink, not just the happy-path log source.
- Add a pipeline unit/integration test that pushes one event of each type (log, metric, trace) through each configured sink before shipping.
- Remember vector validate will not catch this: the panic happens at encode time on the first metric, so only event-type routing guards production.
When it happens
Trigger: Any sink (console, socket, http, file, etc.) configured with encoding.codec = "protobuf" whose input stream contains an Event::Metric: internal_metrics or host_metrics sources, metric sources (prometheus_scrape, statsd, socket metrics), aggregating transforms (aggregate, log_to_metric), or a mixed logs+metrics pipeline without event-type routing. The panic fires at encode time, i.e. on the first metric event, not at config load, so vector validate will not catch it.
Common situations: Piping internal_metrics to a console sink that was set up for log protobuf encoding; pointing one 'everything' sink at both log and metric sources; switching a working log pipeline's codec from json to protobuf while metrics silently share the same sink; assuming protobuf is a drop-in replacement for the json codec.
Related errors
AI-assisted analysis of vectordotdev/vector@711f03abce (2026-08-16).
Data as JSON: /api/errors/4f4dc629509530fd.
Report an issue: GitHub.