{"record":{"id":"6c0ce968ac73bfd6","repo":"risingwavelabs/risingwave","slug":"invalid-backfill-state-cdc-offset","errorCode":null,"errorMessage":"invalid backfill state: cdc_offset","messagePattern":"invalid backfill state: cdc_offset","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/stream/src/executor/backfill/cdc/state.rs","lineNumber":91,"sourceCode":"                    Some(ScalarImpl::Int64(val)) => val,\n                    _ => return Err(anyhow!(\"invalid backfill state: row_count\").into()),\n                };\n                let is_finished = match state[state_len - 3] {\n                    Some(ScalarImpl::Bool(val)) => val,\n                    _ => return Err(anyhow!(\"invalid backfill state: backfill_finished\").into()),\n                };\n                let cdc_offset = match state[state_len - 1] {\n                    Some(ScalarImpl::Jsonb(ref jsonb)) => {\n                        serde_json::from_value(jsonb.clone().take()).unwrap()\n                    }\n                    None if is_finished => None,\n                    None => {\n                        return Err(anyhow!(\n                            \"invalid backfill state: unfinished row has null cdc_offset\"\n                        )\n                        .into());\n                    }\n                    _ => return Err(anyhow!(\"invalid backfill state: cdc_offset\").into()),\n                };\n\n                let current_pk_pos = state[1..state_len - 3].to_vec();\n                Ok(CdcStateRecord {\n                    current_pk_pos: Some(OwnedRow::new(current_pk_pos)),\n                    is_finished,\n                    last_cdc_offset: cdc_offset,\n                    row_count,\n                })\n            }\n            None => Ok(CdcStateRecord::default()),\n        }\n    }\n\n    /// Modify the state of the corresponding split (currently only supports single split)\n    pub async fn mutate_state(\n        &mut self,\n        current_pk_pos: Option<OwnedRow>,","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/stream/src/executor/backfill/cdc/state.rs#L73-L109","documentation":"Thrown by CdcBackfillState::restore_state when the persisted state row for a CDC backfill has an unexpected shape: the cdc_offset element in the state array is neither a valid value nor the expected null. The state table row layout (finished flag, offsets, PK position) does not match what the executor version expects, so recovery is refused rather than silently resuming with corrupt progress.","triggerScenarios":"Restoring a CDC backfill actor whose state table row contains a scalar at the cdc_offset position with an unexpected type (neither a valid offset nor None), e.g. after a partial write, a state-schema change, or reading a row written by an incompatible version.","commonSituations":"Upgrading RisingWave across versions that changed the CDC backfill state row layout; a state table row written by an old migration that did not include the cdc_offset field; manual state-table edits or corrupted persisted state.","solutions":["Cancel and recreate the streaming job (MV/materialized view with CDC source) so backfill restarts from a clean state","Check the RisingWave version the state was written with; roll back to it, let the backfill finish, then upgrade","Inspect the state table row (SELECT the internal state table) to confirm the row layout mismatch","If corruption is isolated, drop and rebuild the affected table/backfill from the upstream CDC source"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Before relying on recovery, inspect the persisted state row types\nlet state = state_store.get_row(...)?.into_inner().into_vec();\nlet cdc_offset_ok = matches!(state.get(STATE_CDC_OFFSET_IDX), None | Some(ScalarImpl::Bytea(_)));\nif !cdc_offset_ok { /* recreate the job instead of resuming */ }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never mutate internal state tables manually","Complete in-progress backfills before cluster upgrades","Keep writer and reader RisingWave versions consistent for the same job"],"tags":["rust","streaming","cdc","state-restore"],"backgroundTag":"invalid-state-transition","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}