risingwavelabs/risingwave · error

current is_checkpoint

Error message

current is_checkpoint {} does not match with decoded is_checkpoint {}

What it means

Companion check to the epoch mismatch above: during replay, the in-memory `current_is_checkpoint` flag (whether the barrier being aligned is a checkpoint barrier) does not match the `is_checkpoint` flag decoded from the row. This means two rows decoded as belonging to the same epoch disagree on checkpoint-ness, so the persisted log is internally inconsistent.

Solutions

  1. Restore the metadata/log store from a consistent snapshot or backup; do not hand-edit the KV store.
  2. Confirm the writing and replaying RisingWave versions match (barrier serialization of `is_checkpoint` may have changed).
  3. If reproducible after a crash, collect the affected key range and file a bug with the recovery logs.
  4. Re-run recovery from the latest checkpoint epoch preceding the corrupted range.

Example fix

// before: manually copying partial metadata between clusters
scanfh meta-kv --range partial-copy
// after: restore a full consistent snapshot
rw meta start --state-store hummock+<original-cluster-snapshot>
Defensive patterns

Strategy: try-catch

Validate before calling

// Validate checkpoint flags are consistent per epoch during a pre-replay scan
let mut flags: HashMap<u64, bool> = HashMap::new();
for row in scanned_rows {
    if let Some(prev) = flags.insert(row.epoch(), row.is_checkpoint()) {
        if prev != row.is_checkpoint() { /* inconsistent epoch flags: abort */ }
    }
}

Type guard

fn checkpoint_flag_consistent(current: bool, decoded: bool) -> bool { current == decoded }

Try / catch

// Rust
match log_store.replay(...).await {
    Err(e) if e.to_string().contains("does not match with decoded is_checkpoint") => {
        // corrupted/partially overwritten log: restore from consistent snapshot and retry
    }
    r => r?,
}

Prevention

When it happens

Trigger: During KV log store replay, when `current_is_checkpoint != &is_checkpoint` for rows with the same decoded epoch — e.g. a checkpoint barrier row and a non-checkpoint row share one epoch, or a duplicated/overwritten row carries a different flag.

Common situations: Corrupted or partially overwritten metadata KV entries after a crash, mixing logs from different clusters/versions, or a bug writing both checkpoint and non-checkpoint rows under one epoch.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/1cebb8f90ed8fba4. Report an issue: GitHub.

Appendix: source

Thrown at src/stream/src/common/log_store_impl/kv_log_store/serde.rs:1087

                    } else {
                        match &mut self.stream_state {
                            StreamState::BarrierAligning {
                                aligned_vnodes,
                                read_size,
                                curr_epoch,
                                is_checkpoint: current_is_checkpoint,
                            } => {
                                aligned_vnodes.set(vnode.to_index(), true);
                                *read_size += size;
                                if curr_epoch != &decoded_epoch {
                                    return Err(anyhow!(
                                        "current epoch {} does not match with decoded epoch {}",
                                        curr_epoch,
                                        decoded_epoch
                                    ));
                                }
                                if current_is_checkpoint != &is_checkpoint {
                                    return Err(anyhow!(
                                        "current is_checkpoint {} does not match with decoded is_checkpoint {}",
                                        current_is_checkpoint,
                                        is_checkpoint
                                    ));
                                }
                            }
                            other => {
                                let mut aligned_vnodes =
                                    BitmapBuilder::zeroed(self.serde.vnodes().len());
                                aligned_vnodes.set(vnode.to_index(), true);
                                *other = StreamState::BarrierAligning {
                                    aligned_vnodes,
                                    read_size: size,
                                    curr_epoch: decoded_epoch,
                                    is_checkpoint,
                                };
                            }
                        }

View on GitHub (pinned to 6469eb736d)