risingwavelabs/risingwave · error
checkpoint missing required field `version`
Error message
checkpoint missing required field `version`
What it means
The decompressed checkpoint payload decoded as PbHummockVersionCheckpoint but lacks the required `version` field, so decode_checkpoint_data rejects it. The `version` field identifies the checkpoint format and is mandatory in the enveloped format.
Solutions
- Ensure the checkpoint was written by a compatible RisingWave version (the legacy path handles old formats)
- Restore the checkpoint object from a backup written by the same version
- If migrating old data, use the legacy decode fallback rather than feeding legacy bytes to the enveloped path
- Check writer code to confirm version is always set when constructing the checkpoint
Example fix
// before (writer)
let ckpt = PbHummockVersionCheckpoint { payload: Some(p), version: None };
// after
let ckpt = PbHummockVersionCheckpoint { payload: Some(p), version: Some(CURRENT_CHECKPOINT_VERSION) }; Defensive patterns
Strategy: validation
Validate before calling
// Writer-side: ensure version is always set before serializing assert!(ckpt.version.is_some(), "checkpoint must carry a version field");
Type guard
fn has_version(ckpt: &PbHummockVersionCheckpoint) -> bool { ckpt.version.is_some() }
Try / catch
match try_read_checkpoint(store, id).await {
Err(e) if e.to_string().contains("missing required field `version`") => {
tracing::warn!("incompatible/corrupt checkpoint {id}: {e:#}");
// fall back to a prior checkpoint or re-bootstrap
}
other => other?,
}
Prevention
- Always set the version field when writing checkpoints
- Avoid mixing checkpoint objects across RisingWave versions
- Validate restored objects before swapping them in
- Keep legacy-format data on the legacy decode path
When it happens
Trigger: decode_checkpoint_data decodes an envelope, decompresses it, and finds ckpt.version == None — i.e. the payload was produced without setting version (legacy/foreign writer) or the payload is corrupt in a way that still decodes.
Common situations: Mixing checkpoint data written by an old RisingWave version with a new enveloped reader; manual manipulation of checkpoint objects; a writer bug that omitted the version field.
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
- legacy 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/15a6b896b793db4a.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/src/hummock/manager/checkpoint.rs:153
expected,
actual
)
.into());
}
let algo = CheckpointCompressionAlgorithm::try_from(envelope.compression_algorithm)
.with_context(|| {
format!(
"unknown checkpoint compression algorithm: {}",
envelope.compression_algorithm
)
})?;
let decompressed = decompress_payload(algo, &envelope.payload)?;
let ckpt = PbHummockVersionCheckpoint::decode(decompressed.as_ref())
.context("failed to decode checkpoint envelope payload")?;
if ckpt.version.is_none() {
return Err(anyhow::anyhow!("checkpoint missing required field `version`").into());
}
tracing::info!(
compression = ?algo,
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"View on GitHub (pinned to 6469eb736d)