apache/iceberg · error · UnsupportedOperationException
WriterSink is used only for writing; committing is handled b
Error message
WriterSink is used only for writing; committing is handled by the main sink
What it means
DynamicIcebergSink's WriterSink is a write-only topology; committing is performed by a separate main sink operator. Its createCommitter always throws UnsupportedOperationException because a committer is intentionally not provided for the writer sub-job.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/DynamicIcebergSink.java:219
this.flinkConfig = flinkConfig;
this.cacheMaximumSize = cacheMaximumSize;
}
@Override
public SinkWriter<DynamicRecordInternal> createWriter(WriterInitContext context) {
return new DynamicWriter(
catalogLoader.loadCatalog(),
writeProperties,
flinkConfig,
cacheMaximumSize,
new DynamicWriterMetrics(context.metricGroup()),
context.getTaskInfo().getIndexOfThisSubtask(),
context.getTaskInfo().getAttemptNumber());
}
@Override
public Committer<DynamicWriteResult> createCommitter(CommitterInitContext context) {
throw new UnsupportedOperationException(
"WriterSink is used only for writing; committing is handled by the main sink");
}
@Override
public SimpleVersionedSerializer<DynamicWriteResult> getCommittableSerializer() {
return new DynamicWriteResultSerializer();
}
}
public static class Builder<T> {
private DataStream<T> input;
private DynamicRecordGenerator<T> generator;
private CatalogLoader catalogLoader;
private String uidPrefix = null;
private final Map<String, String> writeOptions = Maps.newHashMap();
private final Map<String, String> snapshotSummary = Maps.newHashMap();
private ReadableConfig readableConfig = new Configuration();
private TableCreator tableCreator = TableCreator.DEFAULT;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Use the main DynamicIcebergSink's committer path for committing; do not wire the WriterSink as a committing sink.
- If integrating programmatically, only invoke createCommitter on the committer sink's provider, not the writer's.
- Guard custom code with a check of which sink branch is being configured before requesting a committer.
Defensive patterns
Strategy: validation
Validate before calling
if (sinkProvider instanceof WriterSinkProvider) { throw new IllegalStateException("WriterSink cannot commit; use the main sink's committer"); } Try / catch
try { provider.createCommitter(ctx); } catch (UnsupportedOperationException e) { /* route to the main DynamicIcebergSink committer instead */ } Prevention
- Wire committing only through the main DynamicIcebergSink
- Do not call createCommitter on the writer branch
- Keep custom topology code aware of the writer/committer split
When it happens
Trigger: Calling createCommitter on the writer sink's sink provider — e.g. misconfiguring the sink so Flink tries to instantiate a committer for the WriterSink branch, or calling the method directly in custom code.
Common situations: Custom sink topology wiring that expects the writer to also commit; framework changes that probe createCommitter unconditionally.
Related errors
- Unknown row kind:
- Unknown row kind:
- Altering schema is not supported in the old alterTable API.
- Altering partition keys is not supported yet.
- Creating table with computed columns is not supported yet.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/ed7fd5831210ba7d.
Report an issue: GitHub.