risingwavelabs/risingwave · error · SinkError
input data file {} has multiple live position-delete files i
Error message
input data file {} has multiple live position-delete files in snapshot {} What it means
While collecting input delete-vector files, the compaction resolver allows at most one live position-delete file per referenced data file. If `map.insert` finds a second position-delete file referencing the same data file in the snapshot, it fails with this `SinkError::Iceberg` because duplicate delete files are ambiguous and would double-apply deletes.
Source
Thrown at src/stream/src/executor/iceberg_with_pk_index/compaction_resolver.rs:360
// Only delete manifests can carry position-delete files.
if manifest_file.content != ManifestContentType::Deletes {
continue;
}
let manifest = manifest_file.load_manifest(file_io).await?;
for entry in manifest.entries() {
if !entry.is_alive() {
continue;
}
let data_file = entry.data_file();
if data_file.content_type() == DataContentType::PositionDeletes
&& let Some(referenced) = data_file.referenced_data_file()
&& input_paths.contains(referenced.as_str())
{
let positions = read_position_deletes_from_file(file_io, data_file)
.await
.map_err(SinkError::Iceberg)?;
if map.insert(referenced, positions).is_some() {
return Err(SinkError::Iceberg(anyhow!(
"input data file {} has multiple live position-delete files in snapshot {}",
data_file.referenced_data_file().unwrap(),
snapshot.snapshot_id()
)));
}
}
}
}
Ok(map)
}
/// Builds a projection for PK root columns and maps the projected physical order back to the
/// downstream PK order.
fn pk_projection(
parquet_schema: &SchemaDescriptor,
pk_indices: &[usize],
) -> Result<(ProjectionMask, Vec<usize>), SinkError> {
let root_count = parquet_schema.root_schema().get_fields().len();View on GitHub (pinned to 6469eb736d)
Solutions
- Run Iceberg table maintenance/expiring snapshots (e.g. `expire_snapshots`, `remove_orphan_files`) to clean duplicate delete files.
- Check for concurrent writers or a buggy external engine producing duplicate position-delete files and fix the writer.
- If caused by an internal compaction bug, report it with the snapshot id from the error and restore the table from a prior valid snapshot.
Defensive patterns
Strategy: try-catch
Validate before calling
// Before processing, scan the snapshot manifests and count position-delete
// files per referenced data file; abort early if any count > 1.
let mut refs: HashMap<String, usize> = HashMap::new();
for df in position_delete_files(snapshot) {
*refs.entry(df.referenced_data_file().unwrap().into()).or_default() += 1;
}
assert!(refs.values().all(|&c| c == 1), "duplicate position-delete files"); Try / catch
match collect_input_dvs(&snapshot).await {
Err(SinkError::Iceberg(e))
if e.to_string().contains("multiple live position-delete files") => {
// run expire_snapshots / remove_orphan_files, then retry resolution
}
other => other?,
} Prevention
- Run regular Iceberg maintenance: expire_snapshots and remove_orphan_files.
- Avoid multiple concurrent writers appending position-delete files without a compaction strategy.
- Audit third-party writers to confirm they never emit two live delete files for one data file.
When it happens
Trigger: An Iceberg snapshot whose manifest lists two or more live position-delete files whose `referenced_data_file` points at the same input data file included in `input_paths`, encountered in `collect_input_dvs` at src/stream/src/executor/iceberg_with_pk_index/compaction_resolver.rs:360.
Common situations: Corrupted or externally mutated Iceberg tables; compaction bugs that left stale duplicate delete files; third-party writers producing multiple delete files for one data file in a single snapshot.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- position-delete writer produced invalid file count for {data
- compaction resolver sink {} task {} missing resolver task in
- compaction resolver sink {} expected initial begin barrier,
- compaction resolver sink {} task {} expected end barrier, go
- support negative scale for arrow decimal
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/d6f0dd229edc1a38.
Report an issue: GitHub.