risingwavelabs/risingwave · error · StreamExecutorError
iceberg pk-index writer {} expected Begin context for task {
Error message
iceberg pk-index writer {} expected Begin context for task {}, got {:?} What it means
When compaction_begin receives a barrier carrying a compaction context for this sink in Normal mode, that context must be Phase::Begin (entering the compaction flow). Any other phase (Apply/End) indicates a lifecycle inconsistency: the writer is being asked to start a phase that can only occur mid-compaction.
Source
Thrown at src/stream/src/executor/iceberg_with_pk_index/writer.rs:374
}
fn compaction_begin(
&self,
barrier: &Barrier,
) -> StreamExecutorResult<Option<IcebergCompactionTaskId>> {
let context = match barrier.iceberg_pk_index_compaction() {
Some(context) if context.sink_id == self.sink_id => context,
_ => return Ok(None),
};
if context.phase == Phase::End as i32 {
bail!(
"iceberg pk-index writer {} received unexpected End in Normal mode for task {}",
self.sink_id,
context.task_id
);
}
if context.phase != Phase::Begin as i32 {
bail!(
"iceberg pk-index writer {} expected Begin context for task {}, got {:?}",
self.sink_id,
context.task_id,
context.phase
);
}
Ok(Some(context.task_id))
}
#[try_stream(ok = Message, error = StreamExecutorError)]
async fn execute_inner(mut self) {
let mut input = self.input.take().unwrap().execute();
let mut resolver_input = self.resolver_input.take().unwrap().execute();
// Consume the first barrier.
let barrier = expect_first_barrier(&mut input).await?;
let remap_first = expect_first_barrier(&mut resolver_input).await?;
self.validate_aligned_barriers(&barrier, &remap_first)?;View on GitHub (pinned to 6469eb736d)
Solutions
- Identify the observed phase (in the error) vs the expected Begin and trace which barrier was missed.
- Restart the fragment from the last checkpoint to reset the compaction state machine.
- Audit meta's compaction phase scheduling for this task_id to ensure Begin precedes Apply/End.
- Check for actor migration or scale changes that dropped the Begin barrier.
- File a bug with the task id and phase if reproducible.
Defensive patterns
Strategy: validation
Validate before calling
// only dispatch Begin-phase contexts into compaction_begin in Normal mode
if ctx.phase == Phase::Begin as i32 {
writer.compaction_begin(barrier, task).await?;
} Type guard
fn is_begin_phase(ctx: &IcebergPkIndexCompactionContext) -> bool {
ctx.phase == Phase::Begin as i32
} Try / catch
match res {
Err(e) if e.to_string().contains("expected Begin context") => {
error!("compaction phases out of order; restarting fragment from last checkpoint");
}
other => other?,
} Prevention
- Ensure meta emits compaction phases strictly in Begin → Apply → End order.
- Reset writer compaction state on recovery to Normal mode before applying new Begins.
- Audit task rescheduling so phases never leak to a writer that missed Begin.
When it happens
Trigger: Raised in compaction_begin (called from execute_normal) when context.phase != Phase::Begin as i32 — e.g. a Phase::Apply or Phase::End context barrier arrives while the writer is in Normal mode for the task.
Common situations: Missed or mis-ordered Begin barrier after recovery; meta issuing Apply/End phases to a writer that never entered the task; racing phase transitions when tasks are rescheduled across actors; node version skew.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- iceberg pk-index writer {} received unexpected End in Normal
- iceberg pk-index writer {} expected matching {:?} context fo
- iceberg pk-index merger {} received a non-checkpoint compact
- iceberg pk-index writer {} expected checkpoint {:?} starting
- `compaction_interval_sec` must be greater than 0
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/ea842cd8113a521a.
Report an issue: GitHub.