apache/iceberg · error · RuntimeException
Unrecognized write.distribution-mode: ${mode}
Error message
Unrecognized write.distribution-mode: ${mode} What it means
Thrown by IcebergSink when the write.distribution-mode table property resolves to a value the sink does not recognize. Valid values are none, hash, and range (case handled by DistributionMode). The sink uses this property to decide how to shuffle rows before writing; an unknown value cannot be mapped to a distribution strategy.
Source
Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/sink/IcebergSink.java:983
}
}
private DataStream<RowData> distributeDataStream(DataStream<RowData> input) {
DistributionMode mode = flinkWriteConf.distributionMode();
Schema schema = table.schema();
PartitionSpec spec = table.spec();
SortOrder sortOrder = table.sortOrder();
LOG.info("Write distribution mode is '{}'", mode.modeName());
switch (mode) {
case NONE:
return distributeDataStreamByNoneDistributionMode(input, schema);
case HASH:
return distributeDataStreamByHashDistributionMode(input, schema, spec);
case RANGE:
return distributeDataStreamByRangeDistributionMode(input, schema, spec, sortOrder);
default:
throw new RuntimeException("Unrecognized " + WRITE_DISTRIBUTION_MODE + ": " + mode);
}
}
private DataStream<RowData> distributeDataStreamByNoneDistributionMode(
DataStream<RowData> input, Schema iSchema) {
if (equalityFieldIds.isEmpty()) {
return input;
} else {
LOG.info("Distribute rows by equality fields, because there are equality fields set");
return input.keyBy(new EqualityFieldKeySelector(iSchema, flinkRowType, equalityFieldIds));
}
}
private DataStream<RowData> distributeDataStreamByHashDistributionMode(
DataStream<RowData> input, Schema iSchema, PartitionSpec partitionSpec) {
if (equalityFieldIds.isEmpty()) {
if (partitionSpec.isUnpartitioned()) {
LOG.warn(View on GitHub (pinned to 86d9c8fc54)
Solutions
- Set write.distribution-mode to one of: none, hash, or range (e.g. ALTER TABLE ... SET TBLPROPERTIES ('write.distribution-mode'='hash')).
- Remove the write.distribution-mode property entirely so the sink picks its default mode.
- Check DistributionMode.fromName handling and confirm no surrounding whitespace or case-mangling was applied when the property was written.
- If using Flink write distribution options, prefer the sink's mode option over raw table properties to avoid invalid values.
Example fix
// before: table property 'write.distribution-mode' = 'hash-by-key'
// after
ALTER TABLE db.t SET TBLPROPERTIES ('write.distribution-mode'='hash'); Defensive patterns
Strategy: validation
Validate before calling
String mode = table.properties().getOrDefault("write.distribution-mode", "none");
if (!Set.of("none", "hash", "range").contains(mode.toLowerCase(Locale.ROOT))) {
throw new IllegalArgumentException("write.distribution-mode must be none|hash|range, got: " + mode);
} Prevention
- Only set write.distribution-mode from the documented enum values.
- Prefer sink options/API over hand-editing table properties.
- Validate table properties after programmatic construction before submitting jobs.
When it happens
Trigger: Setting the table property write.distribution-mode to a typo or arbitrary string (e.g. 'hashes', 'key', 'NONE ' with whitespace handled upstream, or custom text) and then running a Flink IcebergSink write job.
Common situations: Hand-edited table properties, migration from another engine where a different distribution value was set, copy-pasted config from documentation for a different table, or programmatic property construction with a bad enum string.
Understand the failure class
Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.
Related errors
- Unknown file format %s
- Unknown row kind: <row.getRowKind()>
- Source table %s contains one/all of the reserved property ke
- Unknown row kind:
- Failed to load iceberg table from table loader:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/b9c965a6714d8563.
Report an issue: GitHub.