apache/iceberg · error · RuntimeException
Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${writeMode}
Error message
Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${writeMode} What it means
FlinkSink.distributeDataStream switches on the resolved DistributionMode for the write; if the mode is not NONE, HASH, or RANGE it throws a RuntimeException naming the WRITE_DISTRIBUTION_MODE property and the offending value. This is a defensive default-branch guard — the enum is parsed by FlinkWriteConf, so this only fires when a DistributionMode value escapes validation.
Source
Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/FlinkSink.java:719
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
- Check for duplicate/mixed iceberg-flink-runtime versions on the classpath (mvn dependency:tree, shade config) and pin a single version
- Align the Iceberg runtime jar version used by the cluster and the job (e.g. upgrade iceberg-flink-runtime to match your build)
- Set write-distribution-mode explicitly to none|hash|range so a known-good value is used
- If nothing changed, inspect the log line 'Write distribution mode is ...' to see the resolved mode and trace where it came from
Example fix
// before
builder.set("write-distribution-mode", "batch-shuffle"); // unrecognized
// after
builder.set("write-distribution-mode", DistributionMode.HASH.modeName()); // "hash" Defensive patterns
Strategy: validation
Validate before calling
String mode = writeOptions.getOrDefault("write-distribution-mode", "none");
if (!Set.of("none", "hash", "range").contains(mode.toLowerCase(Locale.ROOT))) {
throw new IllegalArgumentException("unsupported write-distribution-mode: " + mode);
} Try / catch
try {
sinkBuilder.append();
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().contains("Unrecognized")) {
LOG.error("distribution mode rejected: {}", e.getMessage());
// fall back to explicit hash mode
}
throw e;
} Prevention
- Always set write-distribution-mode explicitly to none|hash|range
- Keep iceberg-flink-runtime and compile-time Iceberg versions identical
- Audit fat jars for duplicate org.apache.iceberg classes
- Log the resolved DistributionMode before append() during upgrades
When it happens
Trigger: Builder#distributionMode / write option 'write-distribution-mode' / FlinkWriteOptions.DISTRIBUTION_MODE resolves to a DistributionMode constant outside the three handled cases (no current user-facing value can); effectively only reachable via a newer enum constant running against older sink code, or custom DistributionMode injection.
Common situations: Version mismatch: a Flink job or SQL planner compiled against a newer Iceberg that added an enum value is run with an older iceberg-flink-runtime jar on the classpath; or fat-jar shading mixes two Iceberg versions so the parsed enum differs from the one the sink switch handles.
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}: ${mode}
- Invalid rewrite job order name: %s
- Unknown row-level operation mode:
- Unknown file format %s
- ${tableName}: Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${mod
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/c903b049ca7c8054.
Report an issue: GitHub.