apache/iceberg · error · java.lang.IllegalArgumentException

Unexpected distribution mode:

Error message

Unexpected distribution mode: 

What it means

Thrown by SparkWriteUtil when building a Distribution for COPY-ON-WRITE DELETE/UPDATE/MERGE writes and the table's write distribution mode is not one of the handled values (NONE, HASH, RANGE, or ORDERED). Iceberg validates distribution modes eagerly so misconfiguration fails at plan time rather than producing wrongly shuffled writes.

Source

Thrown at spark/v4.2/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

  1. Check the table's write.distribution-mode property and set it to one of none, hash, or range
  2. Upgrade the Iceberg runtime to a version that supports the mode you configured
  3. Remove the custom/default property override injecting the unknown mode

Example fix

// before
ALTER TABLE t SET TBLPROPERTIES ('write.distribution-mode'='balanced');
// after
ALTER TABLE t SET TBLPROPERTIES ('write.distribution-mode'='hash');
Defensive patterns

Strategy: validation

Validate before calling

String mode = table.properties().getOrDefault(TableProperties.WRITE_DISTRIBUTION_MODE, TableProperties.WRITE_DISTRIBUTION_MODE_NONE);
Preconditions.checkArgument(
    mode.equals(TableProperties.WRITE_DISTRIBUTION_MODE_NONE) ||
    mode.equals(TableProperties.WRITE_DISTRIBUTION_MODE_HASH) ||
    mode.equals(TableProperties.WRITE_DISTRIBUTION_MODE_RANGE),
    "Unsupported write.distribution-mode: %s", mode);

Prevention

When it happens

Trigger: Calling copyOnWriteDeleteUpdateDistribution with a table whose write distribution mode property (write.distribution-mode) parses to a value outside the supported enum set, or a code path passing a custom/unknown SparkWriteUtil.DistributionMode.

Common situations: Typo or unsupported value in write.distribution-mode in table properties, a stale Spark extension writing newer mode values that an older Iceberg runtime does not know, or custom catalog defaults injecting an unexpected mode.

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/8c01e4a708a1fd1b. Report an issue: GitHub.