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

  1. Only pass valid DistributionMode values (NONE, HASH, RANGE) into writeDistribution
  2. Handle the mode before calling: map unknown modes to a supported one or reject earlier with a clear validation error
  3. 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

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


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)