apache/iceberg · error · UnsupportedOperationException
Unsupported delete granularity: ${granularity}
Error message
Unsupported delete granularity: ${granularity} What it means
SortingPositionOnlyDeleteWriter.close() dispatches on the configured DeleteGranularity (FILE, PARTITION, etc.); any other value falls through to default and throws UnsupportedOperationException. This means the writer was configured with a granularity it cannot produce.
Source
Thrown at core/src/main/java/org/apache/iceberg/deletes/SortingPositionOnlyDeleteWriter.java:111
}
@Override
public DeleteWriteResult result() {
return result;
}
@Override
public void close() throws IOException {
if (result == null) {
switch (granularity) {
case FILE:
this.result = writeFileDeletes();
return;
case PARTITION:
this.result = writePartitionDeletes();
return;
default:
throw new UnsupportedOperationException("Unsupported delete granularity: " + granularity);
}
}
}
// write deletes for all data files together
private DeleteWriteResult writePartitionDeletes() throws IOException {
return writeDeletes(positionsByPath.keySet());
}
// write deletes for different data files into distinct delete files
private DeleteWriteResult writeFileDeletes() throws IOException {
List<DeleteFile> deleteFiles = Lists.newArrayList();
CharSequenceSet referencedDataFiles = CharSequenceSet.empty();
List<DeleteFile> rewrittenDeleteFiles = Lists.newArrayList();
for (CharSequence path : positionsByPath.keySet()) {
DeleteWriteResult writeResult = writeDeletes(ImmutableList.of(path));
deleteFiles.addAll(writeResult.deleteFiles());View on GitHub (pinned to 86d9c8fc54)
Solutions
- Configure the writer with DeleteGranularity.FILE or DeleteGranularity.PARTITION
- If a new granularity value was introduced, upgrade Iceberg so the writer supports it, or handle it in writePartitionDeletes-style methods
- Add a case for the new granularity in close() if extending the writer yourself
Example fix
// before
DeleteGranularity granularity = DeleteGranularity.valueOf(cfg); // e.g. NEW_VALUE
// after
if (granularity != DeleteGranularity.FILE && granularity != DeleteGranularity.PARTITION) {
throw new IllegalArgumentException("Sorting writer requires FILE or PARTITION, got: " + granularity);
} Defensive patterns
Strategy: validation
Validate before calling
Preconditions.checkArgument(granularity == DeleteGranularity.FILE || granularity == DeleteGranularity.PARTITION, "Unsupported granularity: %s", granularity);
Type guard
boolean writerSupports(DeleteGranularity g) { return g == DeleteGranularity.FILE || g == DeleteGranularity.PARTITION; } Try / catch
try { writer.close(); } catch (UnsupportedOperationException e) { throw new IllegalArgumentException("Check writer DeleteGranularity config", e); } Prevention
- Validate granularity config at writer construction time, not at close()
- Watch for new DeleteGranularity enum values when upgrading Iceberg and check writer support
- Exhaustive switch over DeleteGranularity with a compile-time-checked expression avoids the default fallthrough
When it happens
Trigger: Constructing a SortingPositionOnlyDeleteWriter with a DeleteGranularity other than FILE or PARTITION (e.g. a newly added enum value the writer does not handle) and then calling close().
Common situations: Enum evolution: a new DeleteGranularity value added to the API but not yet supported by the sorting writer; custom writer configs passing an invalid granularity value.
Related errors
- Invalid file format: %s
- Invalid rewrite job order name: %s
- String.format("Invalid snapshot ref type: %s", snapshotRefTy
- Invalid edge interpolation algorithm: %s
- Invalid isolation level: %s
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/93642ee17a698de8.
Report an issue: GitHub.