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

  1. Set the merge/update distribution-mode to none or hash for merge-on-read operations
  2. Drop the operation-specific property so it inherits a supported default
  3. 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

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


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