risingwavelabs/risingwave · error · BackupError
unsupported metadata snapshot format version for hummock…
Error message
unsupported metadata snapshot format version for hummock sequence partial decoding: {} What it means
decode_hummock_sequences_from_stream reads the snapshot header and requires format_version >= 2 to partially decode hummock sequences; older snapshots throw "unsupported metadata snapshot format version for hummock sequence partial decoding: {}". The partial (streaming) decoder only understands the V2 section layout.
Solutions
- Use MetaSnapshotV1 (full decode) for snapshots with format_version < 2 and read hummock sequences from the fully decoded model.
- Re-create the backup on a current RisingWave version so the snapshot is written in V2 format, then retry.
- Dispatch on the header format_version before choosing the decoder instead of assuming V2.
- If this hits during cluster upgrade, complete the meta store migration to V2 before taking new snapshots.
Example fix
// before: always partial V2 decode
let seqs = decode_hummock_sequences_from_stream(stream).await?;
// after: branch on version
let (version, _) = read_header(&stream).await?;
let seqs = if version >= 2 {
decode_hummock_sequences_from_stream(stream).await?
} else {
MetaSnapshotV1::decode(stream)?.hummock_sequences
}; Defensive patterns
Strategy: fallback
Validate before calling
// read header first and dispatch
let (format_version, _) = read_snapshot_header(&stream).await?;
if format_version < 2 { /* use full V1 decode path instead */ } Type guard
fn supports_partial_decode(format_version: u32) -> bool { format_version >= 2 } Try / catch
match decode_hummock_sequences_from_stream(stream).await {
Ok(seqs) => seqs,
Err(e) if e.to_string().contains("unsupported metadata snapshot format version") => {
log::info!("legacy snapshot; using full decode path");
decode_v1_full(stream).await?
}
Err(e) => return Err(e.into()),
} Prevention
- Check the snapshot header format_version before choosing a decoder.
- Recreate old backups on a current RisingWave version to get V2 snapshots.
- Keep at least one binary version capable of reading each historical snapshot format.
When it happens
Trigger: Calling decode_hummock_sequences_from_stream (directly or via load on a MetaSnapshot decoded as V2) on a snapshot whose header reports format_version 0 or 1.
Common situations: Restoring/inspecting a backup created by an old RisingWave version (pre-V2 snapshot format) with a current binary path that expects V2; a backup taken before the V2 migration; automated tooling assuming all snapshots are V2.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- unexpected bytes after meta snapshot checksum
- BackupStorage error
- Checksum mismatch: expected
- concurrent backup job is not supported: existent job
- Decoding error
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c47ee0382bc5cb4c.
Report an issue: GitHub.
Appendix: source
Thrown at src/storage/backup/src/meta_snapshot_v2.rs:155
};
}
for_all_metadata_models_v2!(define_decode_metadata);
// Metadata V2 is encoded as a positional list of sections. The actual encoded order inserts
// `hummock_version` before `version_stats`, so `hummock_sequences` is section 26:
// 0 seaql_migrations, 1 hummock_version, 2 version_stats, ..., 26 hummock_sequences.
//
// Keep this as a fixed index so partial decoding can skip directly to `hummock_sequences`.
const HUMMOCK_SEQUENCES_METADATA_SECTION_INDEX: usize = 26;
pub async fn decode_hummock_sequences_from_stream(
stream: MonitoredStreamingReader,
) -> BackupResult<Vec<risingwave_meta_model::hummock_sequence::Model>> {
let mut reader = SnapshotPayloadReader::new(ObjectDataStreamReader::new(stream.into_stream()));
let (format_version, _snapshot_id) = reader.read_snapshot_header().await?;
if format_version < 2 {
return Err(BackupError::Other(anyhow!(
"unsupported metadata snapshot format version for hummock sequence partial decoding: {}",
format_version
)));
}
for _ in 0..HUMMOCK_SEQUENCES_METADATA_SECTION_INDEX {
skip_metadata_list(&mut reader).await?;
}
let hummock_sequences = read_n(&mut reader).await?;
reader.finish_after_skipping_to_end().await?;
Ok(hummock_sequences)
}
impl Display for MetadataV2 {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
writeln!(f, "clusters: {:#?}", self.clusters)?;
writeln!(
f,
"Hummock version: id {}, committed_epoch: {:?}",View on GitHub (pinned to 6469eb736d)