risingwavelabs/risingwave · info
Iceberg compaction maintenance was cleared for sink
Error message
Iceberg compaction maintenance was cleared for sink {} What it means
This error is delivered to a manual compaction waiter when the sink's compaction maintenance is cleared (e.g. sink deletion or schedule teardown via clear/stop paths). The pending oneshot waiter is removed and resolved with this Err, and any scheduled task for the sink is cancelled, so the caller learns their manual compaction will never complete.
Solutions
- Treat it as expected cancellation if you dropped or recreated the sink; re-trigger compaction on the new sink
- Check whether another operator/admin cleared maintenance concurrently
- Re-issue the manual compaction once the sink's schedule is re-established
- Coordinate sink lifecycle operations with compaction operations to avoid racing them
Example fix
// before
let task_id = rx.await??; // Err: maintenance cleared
// after
match rx.await {
Ok(Ok(task_id)) => Ok(task_id),
Ok(Err(e)) if e.to_string().contains("maintenance was cleared") => {
info!("compaction cancelled by sink teardown");
Err(SinkCompactionCancelled)
}
r => r,
} Defensive patterns
Strategy: try-catch
Try / catch
match rx.await {
Ok(Ok(task_id)) => Ok(task_id),
Ok(Err(e)) if e.to_string().contains("maintenance was cleared") => {
info!("manual compaction cancelled by sink teardown; not an error if sink was dropped");
Ok(CompactionOutcome::Cancelled)
}
other => other,
} Prevention
- Avoid dropping/recreating the sink while a manual compaction is in flight
- Coordinate sink lifecycle changes with compaction operations
- Treat this error as cancellation, not failure, and re-trigger on the new sink if needed
When it happens
Trigger: A caller awaits the Receiver from start_manual_compaction while clear_compaction_state / sink teardown runs: the waiter is removed from manual_compaction_waiters, the scheduled task is cancelled, and the waiter receives this error.
Common situations: The Iceberg sink (materialized view/sink) is dropped while a manual compaction is pending; admin clears compaction maintenance; meta-side state cleanup after sink recreation.
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
- bounded compaction is not supported for copy-on-write tasks
- compact_with_plan returned no result for a non-empty…
- `compaction.delete_files_count_threshold` must be greater…
- `compaction_interval_sec` must be greater than 0
- `compaction-interval-sec` must be greater than 0 when…
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/1e3ae9bd95e76292.
Report an issue: GitHub.
Appendix: source
Thrown at src/meta/src/manager/iceberg_compaction/schedule.rs:1070
.into()));
}
handles
}
pub fn clear_iceberg_maintenance_by_sink_id(&self, sink_id: SinkId) {
let (task_to_cancel, waiter) = {
let mut guard = self.inner.write();
let task_to_cancel = Self::remove_sink_schedule(&mut guard, sink_id);
guard.snapshot_expiration_sink_ids.remove(&sink_id);
guard.manifest_rewrite_sink_ids.remove(&sink_id);
let waiter = guard.manual_compaction_waiters.remove(&sink_id);
(task_to_cancel, waiter)
};
self.cancel_scheduled_task_if_any(sink_id, task_to_cancel);
if let Some(waiter) = waiter {
let _ = waiter.send(Err(anyhow!(
"Iceberg compaction maintenance was cleared for sink {}",
sink_id
)
.into()));
}
}
fn remove_sink_schedule(
guard: &mut IcebergCompactionManagerInner,
sink_id: SinkId,
) -> Option<ScheduledCompactionTask> {
guard
.sink_schedules
.remove(&sink_id)
.and_then(|track| track.scheduled_task())
}
fn cancel_scheduled_task_if_any(&self, sink_id: SinkId, task: Option<ScheduledCompactionTask>) {View on GitHub (pinned to 6469eb736d)