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

  1. Ensure the checkpoint was written by a compatible RisingWave version (the legacy path handles old formats)
  2. Restore the checkpoint object from a backup written by the same version
  3. If migrating old data, use the legacy decode fallback rather than feeding legacy bytes to the enveloped path
  4. 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

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


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)