apache/iceberg · error · IllegalArgumentException
Unexpected distribution mode: ${mode}
Error message
Unexpected distribution mode: ${mode} What it means
copyOnWriteDeleteUpdateDistribution computes the distribution for copy-on-write DELETE/UPDATE/MERGE writes. Its switch over DistributionMode only handles NONE, HASH, and RANGE; any other value reaches default and throws IllegalArgumentException ('Unexpected distribution mode').
Source
Thrown at spark/v4.0/spark/src/main/java/org/apache/iceberg/spark/SparkWriteUtil.java:161
case NONE:
return Distributions.unspecified();
case HASH:
if (table.spec().isPartitioned()) {
return Distributions.clustered(clustering(table));
} else {
return Distributions.clustered(FILE_CLUSTERING);
}
case RANGE:
if (table.spec().isPartitioned() || table.sortOrder().isSorted()) {
return Distributions.ordered(ordering(table));
} else {
return Distributions.ordered(EXISTING_ROW_ORDERING);
}
default:
throw new IllegalArgumentException("Unexpected distribution mode: " + mode);
}
}
/** Builds requirements for merge-on-read DELETE, UPDATE, MERGE operations. */
public static SparkWriteRequirements positionDeltaRequirements(
Table table,
Command command,
DistributionMode mode,
boolean fanoutEnabled,
long advisoryPartitionSize) {
if (command == UPDATE || command == MERGE) {
Distribution distribution = positionDeltaUpdateMergeDistribution(table, mode);
SortOrder[] ordering = positionDeltaUpdateMergeOrdering(table, fanoutEnabled);
return new SparkWriteRequirements(distribution, ordering, advisoryPartitionSize);
} else {
Distribution distribution = positionDeltaDeleteDistribution(table, mode);
SortOrder[] ordering = fanoutEnabled ? EMPTY_ORDERING : POSITION_DELETE_ORDERING;View on GitHub (pinned to 86d9c8fc54)
Solutions
- Set write.distribution-mode to none, hash, or range
- Ensure a single consistent Iceberg version is on the Spark classpath
- Extend the switch in copyOnWriteDeleteUpdateDistribution if a new mode was introduced
Example fix
// before
default: throw new IllegalArgumentException("Unexpected distribution mode: " + mode);
// after
default: throw new IllegalArgumentException("Unexpected distribution mode: " + mode);
// ensure callers pass only NONE/HASH/RANGE:
Preconditions.checkArgument(mode == DistributionMode.NONE || mode == DistributionMode.HASH || mode == DistributionMode.RANGE, "Mode %s not supported", mode); Defensive patterns
Strategy: validation
Validate before calling
if (mode != DistributionMode.NONE && mode != DistributionMode.HASH && mode != DistributionMode.RANGE) { throw new IllegalArgumentException("Mode not supported for CoW delete/update: " + mode); } Try / catch
try { requirements = SparkWriteUtil.copyOnWriteDeleteUpdateDistribution(table, mode, spec, fanout); } catch (IllegalArgumentException e) { LOG.error("Distribution mode rejected", e); throw e; } Prevention
- Avoid version skew between iceberg-core and iceberg-spark jars
- Use standard write.distribution-mode values
- Review SparkWriteUtil switches when the DistributionMode enum changes
When it happens
Trigger: Invoking the copy-on-write requirements builder when write.distribution-mode is set to a value the switch does not enumerate, or a version mismatch introducing a new DistributionMode constant.
Common situations: Version skew between iceberg-spark and iceberg-core jars on the classpath; misconfigured write.distribution-mode property with an unexpected parsed value.
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:
- 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/b7c5bc0a1ff466bc.
Report an issue: GitHub.