{"record":{"id":"90d51382fbbf168e","repo":"quickwit-oss/quickwit","slug":"dynamic-protobuf-decode-error-wrapped-as-io-error","errorCode":null,"errorMessage":"dynamic protobuf decode error wrapped as io::Error (InvalidData) via map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))","messagePattern":"dynamic protobuf decode error wrapped as io::Error \\(InvalidData\\) via map_err\\(\\|error\\| io::Error::new\\(io::ErrorKind::InvalidData, error\\)\\)","errorType":"exception","errorClass":"io::Error (InvalidData)","httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-proto/src/search/mod.rs","lineNumber":269,"sourceCode":"    pub fn deserialize<R: Read>(mut reader: R) -> io::Result<Self> {\n        let mut version_byte = [0u8; 1];\n        reader.read_exact(&mut version_byte)?;\n\n        if version_byte[0] != FIELDS_METADATA_FORMAT_VERSION {\n            return Err(io::Error::new(\n                io::ErrorKind::InvalidData,\n                format!(\n                    \"unsupported split fields format version: {}\",\n                    version_byte[0]\n                ),\n            ));\n        }\n        let mut zstd_decoder = zstd::stream::read::Decoder::new(reader)?;\n        let mut decompressed = Vec::new();\n        zstd_decoder.read_to_end(&mut decompressed)?;\n\n        Self::decode(&decompressed[..])\n            .map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))\n    }\n}\n\nimpl ListFieldsEntry {\n    pub fn cmp_by_name_and_type(&self, other: &Self) -> Ordering {\n        self.field_name\n            .cmp(&other.field_name)\n            .then_with(|| self.field_type.cmp(&other.field_type))\n    }\n}\n\n#[cfg(test)]\nmod tests {\n    use super::*;\n\n    fn entry(field_name: &str) -> ListFieldsEntry {\n        ListFieldsEntry {\n            field_name: field_name.to_string(),","sourceCodeStart":251,"sourceCodeEnd":287,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-proto/src/search/mod.rs#L251-L287","documentation":"After reading the version byte, `deserialize` zstd-decompresses the remainder and decodes it as a protobuf message with prost's `Self::decode`; any DecodeError is wrapped into io::Error(InvalidData) via map_err. The error therefore indicates valid envelope framing but corrupt/truncated compressed payload or a protobuf body that does not match the schema.","triggerScenarios":"Calling deserialize on metadata whose zstd frame is truncated or corrupt, or whose decompressed bytes are not a valid serialized message — e.g. bytes written by a different schema version that still passes the version check, or bit-corrupted objects in storage.","commonSituations":"Corrupted objects after interrupted uploads; mismatched protobuf schema between writer and reader crates; storage returning wrong object content under the same key; manual payload manipulation in tooling.","solutions":["Inspect the inner prost DecodeError (chained as the io error's source) to identify the failing field.","Regenerate the metadata by re-indexing or re-serializing from a known-good source.","Confirm the quickwit-proto schema used by the reader matches the writer's schema/version.","Check the storage object's integrity (ETag/checksum) against what the writer uploaded."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match SplitFieldsMetadata::deserialize(reader) {\n    Err(e) if e.kind() == std::io::ErrorKind::InvalidData => {\n        // check e.source(): prost DecodeError tells which field failed to decode\n        regenerate_or_reindex()\n    }\n    other => other?,\n}","preventionTips":["Verify object checksums/ETags after uploading split metadata.","Avoid concurrent overwrites of the same metadata key.","Keep protobuf schema changes backward-compatible or bump the version byte."],"tags":["io","protobuf","zstd","serialization","invalid-data"],"backgroundTag":"protobuf-unmarshal-failed","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}