{"record":{"id":"6c12fc5f6d5ed33d","repo":"vectordotdev/vector","slug":"validation-events-are-encoded-by-vector","errorCode":null,"errorMessage":"validation events are encoded by Vector","messagePattern":"validation events are encoded by Vector","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/components/validation/runner/io.rs","lineNumber":50,"sourceCode":"\nimpl From<mpsc::Sender<Vec<Event>>> for EventForwardService {\n    fn from(tx: mpsc::Sender<Vec<Event>>) -> Self {\n        Self { tx }\n    }\n}\n\n#[tonic::async_trait]\nimpl VectorService for EventForwardService {\n    async fn push_events(\n        &self,\n        request: tonic::Request<PushEventsRequest>,\n    ) -> Result<tonic::Response<PushEventsResponse>, Status> {\n        let events = request\n            .into_inner()\n            .events\n            .into_iter()\n            .map(|wrapper| {\n                Event::try_from(wrapper).expect(\"validation events are encoded by Vector\")\n            })\n            .collect();\n\n        self.tx\n            .send(events)\n            .await\n            .expect(\"event forward rx should not close first\");\n\n        Ok(tonic::Response::new(PushEventsResponse {}))\n    }\n\n    async fn health_check(\n        &self,\n        _: tonic::Request<HealthCheckRequest>,\n    ) -> Result<tonic::Response<HealthCheckResponse>, Status> {\n        let message = HealthCheckResponse {\n            status: ServingStatus::Serving.into(),\n        };","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/vectordotdev/vector/blob/bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013/src/components/validation/runner/io.rs#L32-L68","documentation":"In the validation gRPC receiver, each PushEventsRequest event wrapper is converted back into a Vector Event via Event::try_from. The expect asserts that only Vector itself encodes these protobuf events, so conversion must succeed; a panic means the received protobuf event wrapper is malformed or produced by a non-Vector encoder.","triggerScenarios":"push_events receives a PushEventsRequest whose event wrapper fails Event::try_from — corrupt/foreign protobuf payload, mismatched protobuf definitions between client and server, or a non-Vector gRPC client posting events.","commonSituations":"Version skew between the validation client and server crates (protobuf schema drift); a custom test client that does not encode events exactly as Vector does.","solutions":["Ensure the gRPC client encodes events with the same vector protobuf definitions/version as the server.","Regenerate/align protobuf bindings on both sides of the validation pipeline.","Log the failed wrapper (e.g. with prost Debug) instead of a bare expect to identify the malformed event."],"exampleFix":"// before\nEvent::try_from(wrapper).expect(\"validation events are encoded by Vector\")\n// after\nEvent::try_from(wrapper).unwrap_or_else(|e| panic!(\"bad event wrapper: {e:?}\"))","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_valid_event_wrapper(w: &pb::EventWrapper) -> bool {\n    Event::try_from(w.clone()).is_ok()\n}","tryCatchPattern":"match Event::try_from(wrapper) {\n    Ok(ev) => ev,\n    Err(e) => return Status::invalid_argument(format!(\"malformed event wrapper: {e:?}\")),\n}","preventionTips":["Pin the same vector protobuf version on client and server sides of the validation pipeline.","Only send events to the validation gRPC endpoint from Vector's own encoder.","Log malformed wrappers with Debug instead of discarding context in panics."],"tags":["grpc","protobuf","panic","events"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"bdb87aeaa4c4ff27c0ba643c1c77b21bf2ef4013","analyzedAt":"2026-09-16T02:53:35.741Z","contentChangedAt":"2026-09-16T02:53:35.741Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}