apache/iceberg · error · IllegalArgumentException
Unsupported distribution mode:
Error message
Unsupported distribution mode:
What it means
positionDeltaUpdateMergeDistribution() builds the distribution for merge-on-read UPDATE/MERGE operations. Only NONE and HASH are planned here; any other DistributionMode (e.g. RANGE, if unsupported in this code path) hits the default branch and throws IllegalArgumentException. Note the message concatenates mode directly.
Source
Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkWriteUtil.java:176
case NONE:
return Distributions.unspecified();
case HASH:
if (table.spec().isUnpartitioned()) {
return Distributions.clustered(concat(PARTITION_FILE_CLUSTERING, clustering(table)));
} else {
return Distributions.clustered(concat(PARTITION_CLUSTERING, clustering(table)));
}
case RANGE:
if (table.spec().isUnpartitioned()) {
return Distributions.ordered(concat(PARTITION_FILE_ORDERING, ordering(table)));
} else {
return Distributions.ordered(concat(PARTITION_ORDERING, ordering(table)));
}
default:
throw new IllegalArgumentException("Unsupported distribution mode: " + mode);
}
}
private static SortOrder[] positionDeltaUpdateMergeOrdering(Table table, boolean fanoutEnabled) {
if (fanoutEnabled && table.sortOrder().isUnsorted()) {
return EMPTY_ORDERING;
} else {
return concat(POSITION_DELETE_ORDERING, ordering(table));
}
}
private static Distribution positionDeltaDeleteDistribution(Table table, DistributionMode mode) {
switch (mode) {
case NONE:
return Distributions.unspecified();
case HASH:
if (table.spec().isUnpartitioned()) {View on GitHub (pinned to 86d9c8fc54)
Solutions
- Set the merge/update distribution-mode to none or hash for merge-on-read operations
- Drop the operation-specific property so it inherits a supported default
- Upgrade the Spark module if range distribution for positional deltas is needed
Example fix
// before
spark.conf.set("write.merge.distribution-mode", "range")
// after
spark.conf.set("write.merge.distribution-mode", "hash") Defensive patterns
Strategy: validation
Validate before calling
if (mode != DistributionMode.NONE && mode != DistributionMode.HASH) {
throw new IllegalArgumentException("MoR update/merge supports only none/hash, got " + mode);
} Type guard
boolean moRUpdateMergeSupported = mode == DistributionMode.NONE || mode == DistributionMode.HASH;
Try / catch
try {
dist = SparkWriteUtil.positionDeltaUpdateMergeDistribution(table, mode, ...);
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException("Unsupported merge distribution-mode for MoR: " + mode, e);
} Prevention
- Set write.merge.distribution-mode / write.update.distribution-mode to none or hash
- Do not copy CoW range-mode configs onto merge-on-read operations
- Pin the Spark module version and verify supported modes in its docs
When it happens
Trigger: Calling SparkWriteUtil.distribution() for a MoR UPDATE/MERGE where the resolved mode is not NONE or HASH — commonly write.merge.distribution-mode=range on a Spark version that doesn't support range distribution for positional deltas.
Common situations: Users copying CoW recommendations onto MoR operations; job configs with distribution-mode=range for merge operations on tables where it isn't planned.
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
- Unsupported distribution mode: mode
- Unexpected distribution mode: mode
- Unexpected command: command
- Unsupported distribution mode: ${mode}
- Unexpected distribution mode: ${mode}
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/09628b22aac5f0df.
Report an issue: GitHub.