apache/iceberg · error · IllegalArgumentException

Unexpected distribution mode: ${mode}

Error message

Unexpected distribution mode: ${mode}

What it means

copyOnWriteDeleteUpdateDistribution computes the distribution for copy-on-write DELETE/UPDATE/MERGE writes. Its switch over DistributionMode only handles NONE, HASH, and RANGE; any other value reaches default and throws IllegalArgumentException ('Unexpected distribution mode').

Source

Thrown at spark/v4.0/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. Set write.distribution-mode to none, hash, or range
  2. Ensure a single consistent Iceberg version is on the Spark classpath
  3. Extend the switch in copyOnWriteDeleteUpdateDistribution if a new mode was introduced

Example fix

// before
default: throw new IllegalArgumentException("Unexpected distribution mode: " + mode);
// after
default: throw new IllegalArgumentException("Unexpected distribution mode: " + mode);
// ensure callers pass only NONE/HASH/RANGE:
Preconditions.checkArgument(mode == DistributionMode.NONE || mode == DistributionMode.HASH || mode == DistributionMode.RANGE, "Mode %s not supported", mode);
Defensive patterns

Strategy: validation

Validate before calling

if (mode != DistributionMode.NONE && mode != DistributionMode.HASH && mode != DistributionMode.RANGE) { throw new IllegalArgumentException("Mode not supported for CoW delete/update: " + mode); }

Try / catch

try { requirements = SparkWriteUtil.copyOnWriteDeleteUpdateDistribution(table, mode, spec, fanout); } catch (IllegalArgumentException e) { LOG.error("Distribution mode rejected", e); throw e; }

Prevention

When it happens

Trigger: Invoking the copy-on-write requirements builder when write.distribution-mode is set to a value the switch does not enumerate, or a version mismatch introducing a new DistributionMode constant.

Common situations: Version skew between iceberg-spark and iceberg-core jars on the classpath; misconfigured write.distribution-mode property with an unexpected parsed value.

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