risingwavelabs/risingwave · error
legacy checkpoint missing required field `version`
Error message
legacy checkpoint missing required field `version`
What it means
In the legacy (uncompressed, non-enveloped) checkpoint decode path, the PbHummockVersionCheckpoint must still carry a `version` field; its absence means the data predates any known checkpoint format and cannot be interpreted. decode_checkpoint_data fails fast instead of guessing the format.
Solutions
- Restore checkpoint data from a backup produced by a RisingWave version that writes the `version` field
- Verify the object actually is a Hummock version checkpoint (not another protobuf type stored by mistake)
- If the data is truly pre-versioning legacy state, re-bootstrap meta state instead of decoding it
- Check for mixed-version deployment issues (old nodes writing checkpoints read by new nodes)
Defensive patterns
Strategy: fallback
Validate before calling
// Before trusting restored data, check it is a versioned checkpoint
let probe = PbHummockVersionCheckpoint::decode(bytes.as_ref())?;
if probe.version.is_none() { /* treat as incompatible legacy data */ }
Type guard
fn is_legacy_unversioned(ckpt: &PbHummockVersionCheckpoint) -> bool { ckpt.version.is_none() }
Try / catch
match decode_checkpoint_data(bytes, size) {
Err(e) if e.to_string().contains("legacy checkpoint missing required field `version`") => {
tracing::warn!("pre-versioning checkpoint data; re-bootstrap meta state");
Err(e)
}
other => other,
}
Prevention
- Restore meta state only from backups of matching or newer versions
- Verify object provenance before restoring checkpoint files
- Plan migrations with explicit state re-bootstrap steps
- Avoid mixed old/new writer clusters sharing one object store
When it happens
Trigger: decode_checkpoint_data falls back to the legacy path (envelope decode failed), decodes raw bytes as PbHummockVersionCheckpoint, and finds ckpt.version == None.
Common situations: Reading checkpoint data written by a very old RisingWave release before versioning existed; corrupted bytes that happen to decode but lack version; hand-restored checkpoint objects from incompatible backups.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- checkpoint missing required field `version`
- checkpoint checksum mismatch: expected
- Can't find
- Can't find message proto
- empty commit metadata
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/c199a2acbaec11f8.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/src/hummock/manager/checkpoint.rs:176
compressed_size = envelope.payload.len(),
decompressed_size = decompressed.len(),
compression_ratio =
format!("{:.2}x", decompressed.len() as f64 / envelope.payload.len().max(1) as f64),
checksum = format!("{expected:#x}"),
"decoded compressed checkpoint"
);
return Ok(ckpt);
}
// Legacy uncompressed format
tracing::info!(
data_size,
"decoding checkpoint in legacy uncompressed format"
);
let ckpt =
PbHummockVersionCheckpoint::decode(data).context("failed to decode legacy checkpoint")?;
if ckpt.version.is_none() {
return Err(anyhow::anyhow!("legacy checkpoint missing required field `version`").into());
}
Ok(ckpt)
}
fn decompress_payload(
algo: CheckpointCompressionAlgorithm,
payload: &[u8],
) -> Result<std::borrow::Cow<'_, [u8]>> {
use anyhow::Context;
match algo {
CheckpointCompressionAlgorithm::CheckpointCompressionUnspecified => Ok(payload.into()),
CheckpointCompressionAlgorithm::CheckpointCompressionZstd => {
Ok(zstd::stream::decode_all(payload)
.map(std::borrow::Cow::Owned)
.context("zstd decompression failed")?)
}
CheckpointCompressionAlgorithm::CheckpointCompressionLz4 => {View on GitHub (pinned to 6469eb736d)