apache/iceberg · error · RuntimeException
Unrecognized write.distribution-mode:
Error message
Unrecognized write.distribution-mode:
What it means
distributeDataStream switches on the table's write.distribution-mode; the default branch throws when the mode string is not none/hash/range. The library only implements those three distribution strategies for the pre-write topology.
Source
Thrown at flink/v2.2/flink/src/main/java/org/apache/iceberg/flink/sink/FlinkSink.java:721
shuffleStream = shuffleStream.uid(uidPrefix + "-shuffle");
}
return shuffleStream
.partitionCustom(new RangePartitioner(iSchema, sortOrder), r -> r)
.flatMap(
(FlatMapFunction<StatisticsOrRecord, RowData>)
(statisticsOrRecord, out) -> {
if (statisticsOrRecord.hasRecord()) {
out.collect(statisticsOrRecord.record());
}
})
// Set the parallelism same as writerParallelism to
// promote operator chaining with the downstream writer operator
.setParallelism(writerParallelism)
.returns(RowData.class);
default:
throw new RuntimeException("Unrecognized " + WRITE_DISTRIBUTION_MODE + ": " + writeMode);
}
}
}
/**
* Clean up after removing {@link Builder#tableSchema}
*
* @deprecated since 1.10.0, will be removed in 2.0.0. Use {@link #toFlinkRowType(Schema,
* ResolvedSchema)} instead.
*/
@Deprecated
static RowType toFlinkRowType(Schema schema, TableSchema requestedSchema) {
if (requestedSchema != null) {
// Convert the flink schema to iceberg schema using the table schema as the reference.
Schema writeSchema = FlinkSchemaUtil.convert(schema, requestedSchema);
TypeUtil.validateWriteSchema(schema, writeSchema, true, true);
// We use this flink schema to read values from RowData. The flink's TINYINT and SMALLINT willView on GitHub (pinned to 86d9c8fc54)
Solutions
- Set write.distribution-mode to one of none, hash, or range (or remove the property to use the default).
- Check the exact value: ALTER TABLE ... SET TBLPROPERTIES ('write.distribution-mode'='hash').
- Upgrade the iceberg-flink-runtime if the mode was introduced by a newer version.
Example fix
// before
properties.put("write.distribution-mode", "key-by");
// after
properties.put("write.distribution-mode", "hash"); Defensive patterns
Strategy: validation
Validate before calling
String mode = table.properties().getOrDefault("write.distribution-mode", "none");
if (!java.util.Set.of("none", "hash", "range").contains(mode.toLowerCase(java.util.Locale.ROOT))) {
throw new IllegalArgumentException("unsupported write.distribution-mode: " + mode);
} Try / catch
try {
sink.append();
} catch (RuntimeException e) {
if (e.getMessage().contains("write.distribution-mode")) {
// fix the table property then resubmit
}
throw e;
} Prevention
- Only set distribution-mode to none/hash/range.
- Set table properties via SQL/catalog APIs, not manual edits.
- Keep engine and Flink runtime versions aligned.
When it happens
Trigger: Setting table property write.distribution-mode to an unrecognized value (typo like 'hashes', mixed case after custom parsing, or a future/newer value read by an older runtime) before FlinkSink.append().
Common situations: Hand-editing table properties; a table created by a newer Iceberg/Spark writer using a mode the Flink runtime doesn't know; configuration copied from another engine with extra values.
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
- Unrecognized write.distribution-mode:
- ${tableName}: Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${mod
- Unrecognized :
- Unknown file format %s
- : Unrecognized write.distribution-mode:
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/46ab9a1cae1e0727.
Report an issue: GitHub.