risingwavelabs/risingwave · error · HummockError
compact_with_plan returned no result for a non-empty iceberg
Error message
compact_with_plan returned no result for a non-empty iceberg compaction plan
What it means
After dispatching a non-empty compaction plan, the runner calls compact_with_plan and expects Option<CompactionResult>. For a non-empty plan the engine must always return Some; None means the compaction engine produced no result at all. Since this violates the runner's contract with the compaction engine, it is converted into a HummockError::compaction_executor and the task fails instead of committing partial state.
Source
Thrown at src/storage/src/hummock/compactor/iceberg_compaction/iceberg_compactor_runner.rs:512
.await
.map_err(|e| HummockError::compaction_executor(e.as_report()))?;
let pk_index_result = build_pk_index_compaction_result(
&table,
data_files,
pk_index_input_file_paths,
pk_index_read_snapshot_id,
)?;
return Ok((stats, Some(pk_index_result)));
}
let compaction_result = compaction
.compact_with_plan(compaction_plan, &compaction_execution_config)
.await
.map_err(|e| HummockError::compaction_executor(e.as_report()))?
.ok_or_else(|| {
HummockError::compaction_executor(anyhow::anyhow!(
"compact_with_plan returned no result for a non-empty iceberg compaction plan"
))
})?;
let CompactionResult {
data_files,
stats,
table,
} = compaction_result;
if let (Some(committed_table), Some(cow_publish_plan)) = (table, cow_publish_plan) {
publish_cow_snapshot_to_main(
task_id,
&compaction,
&committed_table,
&branch,
&cow_publish_plan,
data_files,View on GitHub (pinned to 6469eb736d)
Solutions
- Retry the compaction task — if transient, a fresh plan will be produced by meta.
- Check compactor logs just before the error for evidence of dropped file groups or canceled rewrites (cancellation, file-not-found during rewrite).
- Verify the pinned snapshot still exists on the table (a concurrently expired snapshot can leave the plan empty); reduce snapshot expiry pressure or re-run.
- If reproducible with a consistent plan, this is an internal invariant violation — report with logs and the compaction plan.
Defensive patterns
Strategy: retry
Try / catch
match compaction.compact_with_plan(plan, &exec_cfg).await {
Ok(Some(result)) => commit(result),
Ok(None) if plan.file_group.data_files.is_empty() => Ok(Drained),
Ok(None) => { tracing::error!("invariant: empty result for non-empty plan"); Err(invariant_violation()) }
Err(e) => Err(e),
} Prevention
- Avoid running concurrent snapshot-expiry while COW compaction is publishing.
- Monitor for frequent occurrences — each one is an internal invariant break worth a bug report.
- Keep compactor and iceberg engine library versions consistent across nodes.
When it happens
Trigger: compact_with_plan resolves to Ok(None) even though compaction_plan contained file groups — an internal invariant break in the iceberg compaction engine (e.g. plan emptied between planning and execution without signalling Drained).
Common situations: Race or bug where all planned file groups became ineligible mid-execution but the engine returned None instead of an empty/drain result; concurrency bugs in the rewrite executor; upgrading iceberg-rust library versions that changed empty-result semantics.
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
- COW compaction must produce at most one table-scoped plan, g
- Data file should not in task deletes
- Manual iceberg compaction task {} for sink {} failed: {}
- No iceberg compactor available
- Manual iceberg compaction waiter dropped unexpectedly for si
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/97a383fca89fdd7b.
Report an issue: GitHub.