apache/iceberg · error · IllegalArgumentException

${tableName}: Unrecognized write.distribution-mode: ${mode}

Error message

${tableName}: Unrecognized write.distribution-mode: ${mode}

What it means

HashKeyGenerator.getKeySelector maps a table's write.distribution-mode to a Flink KeySelector. The switch only handles NONE/HASH kinds of modes it supports; any other string value is rejected with this IllegalArgumentException. The mode comes from table properties, so an unexpected value means misconfiguration or an unparseable distribution mode.

Source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/sink/dynamic/HashKeyGenerator.java:194

        if (equalityFields.isEmpty()) {
          LOG.warn(
              "{}: Fallback to use 'none' distribution mode, because there are no equality fields set "
                  + "and {}='range' is not supported yet in flink",
              tableName,
              WRITE_DISTRIBUTION_MODE);
          return tableKeySelector(tableName, writeParallelism, maxWriteParallelism);
        } else {
          LOG.info(
              "{}: Distribute rows by equality fields, because there are equality fields set "
                  + "and {}='range' is not supported yet in flink",
              tableName,
              WRITE_DISTRIBUTION_MODE);
          return equalityFieldKeySelector(
              tableName, schema, equalityFields, writeParallelism, maxWriteParallelism);
        }

      default:
        throw new IllegalArgumentException(
            tableName + ": Unrecognized " + WRITE_DISTRIBUTION_MODE + ": " + mode);
    }
  }

  private static KeySelector<RowData, Integer> equalityFieldKeySelector(
      String tableName,
      Schema schema,
      Set<String> equalityFields,
      int writeParallelism,
      int maxWriteParallelism) {
    return new TargetLimitedKeySelector(
        new EqualityFieldKeySelector(
            schema,
            FlinkSchemaUtil.convert(schema),
            DynamicSinkUtil.getEqualityFieldIds(equalityFields, schema)),
        tableName,
        writeParallelism,
        maxWriteParallelism);

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Set write.distribution-mode to a supported value: none, hash, or range.
  2. Remove the property to fall back to the connector default.
  3. Upgrade the Iceberg Flink connector if the mode is valid but newer than the connector.

Example fix

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

Strategy: validation

Validate before calling

String mode = table.properties().getOrDefault("write.distribution-mode", "none");
Set<String> allowed = Set.of("none", "hash", "range");
if (!allowed.contains(mode.toLowerCase(Locale.ROOT))) {
  throw new IllegalArgumentException("Unsupported write.distribution-mode: " + mode);
}

Try / catch

try {
  keySelector = generator.keySelector(table, schema, ...);
} catch (IllegalArgumentException e) {
  if (e.getMessage().contains("Unrecognized write.distribution-mode")) {
    keySelector = fallbackKeySelector;
  } else throw e;
}

Prevention

When it happens

Trigger: Calling keySelector() for a table whose write.distribution-mode property is set to an unrecognized value (e.g. typo, 'ring', or a mode added in a newer spec that this connector version does not know).

Common situations: Setting write.distribution-mode to an invalid string in table properties, using a newer Iceberg table mode value with an older Flink connector, or programmatic builds that pass a wrong DistributionMode 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/4ef96d93c0f1abe9. Report an issue: GitHub.