apache/iceberg · error · java.lang.IllegalArgumentException
Unsupported distribution mode:
Error message
Unsupported distribution mode:
What it means
SparkWriteUtil.writeDistribution builds a Spark Distribution from a DistributionMode. NONE is handled implicitly (unspecified), HASH yields clustered, RANGE yields ordered; any other mode value reaching the switch default throws IllegalArgumentException 'Unsupported distribution mode', meaning the configured/derived mode is not a recognized DistributionMode enum value.
Solutions
- Only pass valid DistributionMode values (NONE, HASH, RANGE) into writeDistribution
- Handle the mode before calling: map unknown modes to a supported one or reject earlier with a clear validation error
- Upgrade Iceberg if a newly added DistributionMode needs support in this util
Example fix
// before
Distribution dist = SparkWriteUtil.writeDistribution(table, someUnknownMode); // throws
// after
DistributionMode mode = someUnknownMode == null ? DistributionMode.NONE : someUnknownMode;
Preconditions.checkArgument(
mode == DistributionMode.NONE || mode == DistributionMode.HASH || mode == DistributionMode.RANGE,
"Unsupported distribution mode: %s", mode);
Distribution dist = SparkWriteUtil.writeDistribution(table, mode); Defensive patterns
Strategy: validation
Validate before calling
if (mode != DistributionMode.NONE
&& mode != DistributionMode.HASH
&& mode != DistributionMode.RANGE) {
throw new IllegalArgumentException("Unsupported distribution mode: " + mode);
} Type guard
boolean isWritableMode(DistributionMode m) {
return m == DistributionMode.NONE || m == DistributionMode.HASH || m == DistributionMode.RANGE;
} Try / catch
try { dist = SparkWriteUtil.writeDistribution(table, mode); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Unsupported distribution mode")) { dist = null; /* fall back to unspecified distribution */ } else throw e; } Prevention
- Only configure write distribution/order via known mode names (none/hash/range)
- Validate mode config values before building requirements
- Keep DistributionMode enum handling exhaustive in custom utils
When it happens
Trigger: Calling SparkWriteUtil.writeDistribution with a mode other than NONE/HASH/RANGE, or a DistributionMode value that was corrupted/deserialized incorrectly, during Spark write requirement planning for Iceberg tables.
Common situations: Passing a custom or null-derived DistributionMode through custom write requirement builders; deserialization mismatch after upgrades where a new mode was added but the util switch wasn't updated.
Related errors
- Unexpected distribution mode:
- Unsupported distribution mode:
- Already closed files for partition:
- ALTER TABLE contains multiple distribution clauses
- ALTER TABLE contains multiple distribution clauses
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/0d72b212dd6d9bb6.
Report an issue: GitHub.
Appendix: source
Thrown at spark/v4.2/spark/src/main/java/org/apache/iceberg/spark/SparkWriteUtil.java:118
Distribution distribution = writeDistribution(table, mode);
SortOrder[] ordering = writeOrdering(table, fanoutEnabled);
return new SparkWriteRequirements(distribution, ordering, advisoryPartitionSize);
}
private static Distribution writeDistribution(Table table, DistributionMode mode) {
switch (mode) {
case NONE:
return Distributions.unspecified();
case HASH:
return Distributions.clustered(clustering(table));
case RANGE:
return Distributions.ordered(ordering(table));
default:
throw new IllegalArgumentException("Unsupported distribution mode: " + mode);
}
}
/** Builds requirements for copy-on-write DELETE, UPDATE, MERGE operations. */
public static SparkWriteRequirements copyOnWriteRequirements(
Table table,
Command command,
DistributionMode mode,
boolean fanoutEnabled,
long advisoryPartitionSize) {
if (command == DELETE || command == UPDATE) {
Distribution distribution = copyOnWriteDeleteUpdateDistribution(table, mode);
SortOrder[] ordering = writeOrdering(table, fanoutEnabled);
return new SparkWriteRequirements(distribution, ordering, advisoryPartitionSize);
} else {
return writeRequirements(table, mode, fanoutEnabled, advisoryPartitionSize);
}View on GitHub (pinned to 86d9c8fc54)