{"record":{"id":"4f4dc629509530fd","repo":"vectordotdev/vector","slug":"not-implemented","errorCode":null,"errorMessage":"not implemented","messagePattern":"not implemented","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"lib/codecs/src/encoding/format/protobuf.rs","lineNumber":124,"sourceCode":"            options: options.clone(),\n        })\n    }\n\n    /// Get a description of the message type used in serialization.\n    pub fn descriptor_proto(&self) -> &prost_reflect::prost_types::DescriptorProto {\n        self.message_descriptor.descriptor_proto()\n    }\n}\n\nimpl Encoder<Event> for ProtobufSerializer {\n    type Error = vector_common::Error;\n\n    fn encode(&mut self, event: Event, buffer: &mut BytesMut) -> Result<(), Self::Error> {\n        let message = match event {\n            Event::Log(log) => {\n                encode_message(&self.message_descriptor, log.into_parts().0, &self.options)\n            }\n            Event::Metric(_) => unimplemented!(),\n            Event::Trace(trace) => encode_message(\n                &self.message_descriptor,\n                Value::Object(trace.into_parts().0),\n                &self.options,\n            ),\n        }?;\n        message.encode(buffer).map_err(Into::into)\n    }\n}\n","sourceCodeStart":106,"sourceCodeEnd":134,"githubUrl":"https://github.com/vectordotdev/vector/blob/711f03abce4f7a65e3a84b8893be60675a8aef39/lib/codecs/src/encoding/format/protobuf.rs#L106-L134","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# vector.toml — before: metrics and logs share a protobuf sink (panics on first metric)\n[sinks.out]\ntype = \"console\"\ninputs = [\"internal_metrics\", \"my_log_source\"]\n[sinks.out.encoding]\ncodec = \"protobuf\"\n[sinks.out.encoding.protobuf]\ndesc_file = \"./protos/event.desc\"\nmessage_type = \"log.Event\"\n\n# after: route by event type, metrics use a metric-capable codec\n[transforms.split]\ntype = \"route\"\ninputs = [\"internal_metrics\", \"my_log_source\"]\nroute.logs = 'type == \"log\"'\nroute.metrics = 'type == \"metric\"'\n\n[sinks.out]\ntype = \"console\"\ninputs = [\"split.logs\"]\n[sinks.out.encoding]\ncodec = \"protobuf\"\n[sinks.out.encoding.protobuf]\ndesc_file = \"./protos/event.desc\"\nmessage_type = \"log.Event\"\n\n[sinks.metrics_out]\ntype = \"console\"\ninputs = [\"split.metrics\"]\n[sinks.metrics_out.encoding]\ncodec = \"json\"","handlingStrategy":"validation","validationCode":"# Rust API users: never hand Event::Metric to the protobuf serializer\nif matches!(event, Event::Metric(_)) {\n    return route_to_metric_sink(event); // codec supports only Log and Trace\n}\nserializer.encode(event, &mut buffer)?;\n\n# Config users: assert before deploy that every protobuf sink only receives logs\n# with a route transform: route.logs = 'type == \"log\"' (or 'type != \"metric\"')","typeGuard":"fn protobuf_encodable(event: &Event) -> bool {\n    !matches!(event, Event::Metric(_)) // Log and Trace arms are implemented\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["protobuf","codec","metrics","sink","panic","rust"],"backgroundTag":"codec-unsupported-event-type","analyzedSha":"711f03abce4f7a65e3a84b8893be60675a8aef39","analyzedAt":"2026-08-16T23:17:25.807Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}