apache/iceberg · error · IllegalArgumentException

Unsupported distribution mode: mode

Error message

Unsupported distribution mode: mode

What it means

SparkWriteUtil.writeDistribution() builds a Spark Distribution for a write based on the resolved DistributionMode. NONE and HASH/clustered and RANGE/ordered are handled; any other mode value throws IllegalArgumentException. This is a guard against an unexpected mode reaching the physical planning code.

Source

Thrown at spark/v3.5/spark/src/main/java/org/apache/iceberg/spark/SparkWriteUtil.java:88

    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)

Solutions

  1. Set write.distribution-mode (or the operation-specific override) to one of none, hash, or range
  2. Validate/normalize the mode string before it becomes a DistributionMode (SparkWriteConf already parses case-insensitively; check for typos)
  3. Upgrade the Spark module if a new mode (e.g. from a newer spec) must be planned

Example fix

// before
spark.conf.set("write.distribution-mode", "partitioned")
// after
spark.conf.set("write.distribution-mode", "hash")
Defensive patterns

Strategy: validation

Validate before calling

String modeStr = spark.conf().get("write.distribution-mode", "none").toLowerCase(Locale.ROOT);
if (!Set.of("none", "hash", "range").contains(modeStr)) {
  throw new IllegalArgumentException("write.distribution-mode must be none, hash, or range");
}

Type guard

boolean isPlannableMode = mode == DistributionMode.NONE || mode == DistributionMode.HASH || mode == DistributionMode.RANGE;

Try / catch

try {
  Distribution dist = SparkWriteUtil.writeDistribution(table, mode);
} catch (IllegalArgumentException e) {
  LOG.error("DistributionMode {} not supported by this Spark version", mode);
  throw e;
}

Prevention

When it happens

Trigger: Calling SparkWriteUtil.writeDistribution(...) with a DistributionMode other than NONE, HASH, or RANGE — typically a future/unrecognized enum value or a mode resolved from a misconfigured write.distribution-mode property.

Common situations: Users set write.distribution-mode to a typo'd or unsupported value; custom catalogs/extensions resolve their own DistributionMode that this Spark version doesn't map to a Distribution.

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


AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12). Data as JSON: /api/errors/7597a4d03639589b. Report an issue: GitHub.