apache/iceberg · error · RuntimeException

Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${mode}

Error message

Unrecognized ${WRITE_DISTRIBUTION_MODE}: ${mode}

What it means

IcebergSink.distributeDataStream switches on the DistributionMode resolved from write config; the default branch throws RuntimeException 'Unrecognized WRITE_DISTRIBUTION_MODE: <mode>' for any value other than NONE, HASH, or RANGE. Like the FlinkSink equivalent, it is a defensive guard against an unhandled enum constant, typically caused by classpath/version skew.

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/sink/IcebergSink.java:983

    }
  }

  private DataStream<RowData> distributeDataStream(DataStream<RowData> input) {
    DistributionMode mode = flinkWriteConf.distributionMode();
    Schema schema = table.schema();
    PartitionSpec spec = table.spec();
    SortOrder sortOrder = table.sortOrder();

    LOG.info("Write distribution mode is '{}'", mode.modeName());
    switch (mode) {
      case NONE:
        return distributeDataStreamByNoneDistributionMode(input, schema);
      case HASH:
        return distributeDataStreamByHashDistributionMode(input, schema, spec);
      case RANGE:
        return distributeDataStreamByRangeDistributionMode(input, schema, spec, sortOrder);
      default:
        throw new RuntimeException("Unrecognized " + WRITE_DISTRIBUTION_MODE + ": " + mode);
    }
  }

  private DataStream<RowData> distributeDataStreamByNoneDistributionMode(
      DataStream<RowData> input, Schema iSchema) {
    if (equalityFieldIds.isEmpty()) {
      return input;
    } else {
      LOG.info("Distribute rows by equality fields, because there are equality fields set");
      return input.keyBy(new EqualityFieldKeySelector(iSchema, flinkRowType, equalityFieldIds));
    }
  }

  private DataStream<RowData> distributeDataStreamByHashDistributionMode(
      DataStream<RowData> input, Schema iSchema, PartitionSpec partitionSpec) {
    if (equalityFieldIds.isEmpty()) {
      if (partitionSpec.isUnpartitioned()) {
        LOG.warn(

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Set the mode explicitly to a supported value: none, hash, or range (via FlinkWriteOptions.DISTRIBUTION_MODE or write options)
  2. Ensure one consistent iceberg-flink-runtime version across job jar and cluster classpath
  3. Check the sink's log line 'Write distribution mode is ...' to confirm what value was parsed and from which config source
  4. Upgrade or downgrade the runtime jar so the parsed enum matches the sink's supported set

Example fix

// before
FlinkWriteOptions.DISTRIBUTION_MODE.key() -> "adaptive"  // newer mode, old sink
// after
Map<String, String> opts = Map.of("write-distribution-mode", "hash");
IcebergSink.forRowData(input).writeOptions(opts).tableLoader(loader).append();
Defensive patterns

Strategy: validation

Validate before calling

DistributionMode mode = flinkWriteConf.distributionMode();
if (mode != DistributionMode.NONE && mode != DistributionMode.HASH && mode != DistributionMode.RANGE) {
  throw new IllegalArgumentException("unsupported distribution mode: " + mode);
}

Try / catch

try {
  sink.append();
} catch (RuntimeException e) {
  if (String.valueOf(e.getMessage()).contains("Unrecognized" + " " + FlinkWriteOptions.DISTRIBUTION_MODE.key())) {
    LOG.error("bad distribution mode resolved; check write options and jar versions");
  }
  throw e;
}

Prevention

When it happens

Trigger: write.distribution-mode (FlinkWriteOptions.DISTRIBUTION_MODE / FlinkWriteConf) resolving to a DistributionMode constant not covered by the switch — practically only via mixed Iceberg versions or a future enum value run against this older sink code.

Common situations: iceberg-flink-runtime jar on the cluster differs from the one the job was compiled against; shaded dependencies bundling a second Iceberg; copying config from a newer Iceberg release introducing a new mode name.

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