quickwit-oss/quickwit · error · io::Error (InvalidData)
unsupported split recovery metadata format version: {version
Error message
unsupported split recovery metadata format version: {version} What it means
After the magic header validates, `SplitRecoveryMetadata::deserialize` reads a one-byte format version and compares it against SPLIT_RECOVERY_METADATA_FORMAT_VERSION. A valid envelope written by a different (older or newer) format version is rejected with InvalidData.
Source
Thrown at quickwit/quickwit-proto/src/metastore/mod.rs:69
.expect("encoding a protobuf into a Vec should not fail");
output
}
/// Deserializes split recovery metadata embedded in a split bundle.
pub fn deserialize(mut bytes: &[u8]) -> io::Result<Self> {
use prost::Message;
if bytes.len() < SPLIT_RECOVERY_METADATA_HEADER_LEN
|| &bytes[..SPLIT_RECOVERY_METADATA_MAGIC.len()] != SPLIT_RECOVERY_METADATA_MAGIC
{
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"invalid split recovery metadata magic number",
));
}
let version = bytes[SPLIT_RECOVERY_METADATA_MAGIC.len()];
if version != SPLIT_RECOVERY_METADATA_FORMAT_VERSION {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("unsupported split recovery metadata format version: {version}"),
));
}
bytes = &bytes[SPLIT_RECOVERY_METADATA_HEADER_LEN..];
Self::decode(bytes).map_err(|error| io::Error::new(io::ErrorKind::InvalidData, error))
}
}
#[cfg(test)]
mod split_recovery_metadata_tests {
use super::SplitRecoveryMetadata;
use crate::types::{DocMappingUid, IndexUid};
#[test]
fn test_split_recovery_metadata_roundtrip_and_unknown_fields() {
let metadata = SplitRecoveryMetadata {
split_id: "split-a".to_string(),View on GitHub (pinned to a39730c5cd)
Solutions
- Align all Quickwit nodes to one version so the format version matches.
- Discard and regenerate recovery metadata created by the incompatible version.
- If a migration is needed, upgrade through the release that supports the old version rather than jumping directly.
- Inspect the version byte in the blob to identify which writer produced it.
Defensive patterns
Strategy: validation
Validate before calling
fn version_supported(bytes: &[u8]) -> bool {
bytes.len() >= 6 && bytes[5] == SPLIT_RECOVERY_METADATA_FORMAT_VERSION
} Try / catch
match SplitRecoveryMetadata::deserialize(&bytes) {
Err(e) if e.to_string().contains("format version") => {
// blob written by another Quickwit version: migrate or regenerate
}
other => other?,
} Prevention
- Keep all cluster nodes on the same Quickwit version.
- During rolling upgrades, finish draining old-format metadata before removing old binaries.
- Record the writer version alongside serialized blobs for diagnostics.
When it happens
Trigger: Deserializing a blob whose magic matches but whose version byte differs from the current SPLIT_RECOVERY_METADATA_FORMAT_VERSION — typically data written by another Quickwit release.
Common situations: Rolling upgrades/downgrades where nodes with different versions read each other's recovery metadata; restoring backups produced by an older release; replaying queued messages from a previous format.
Related errors
- unsupported split fields format version: {version_byte[0]}
- invalid split recovery metadata magic number
- unsupported split recovery metadata format version: {version
- dynamic protobuf decode error wrapped as io::Error (InvalidD
- `doc_batch` should not be empty
AI-assisted analysis of quickwit-oss/quickwit@a39730c5cd (2026-09-08).
Data as JSON: /api/errors/ce22fa19579bf812.
Report an issue: GitHub.