apache/iceberg · error · UnsupportedOperationException

Unsupported table change: setting unique key constraints.

Error message

Unsupported table change: setting unique key constraints.

What it means

applyUniqueConstraint maps PRIMARY_KEY constraints to Iceberg identifier fields, but Iceberg has no notion of UNIQUE_KEY constraints, so UniqueConstraint.Type.UNIQUE_KEY throws UnsupportedOperationException.

Source

Thrown at flink/v2.1/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java:253

    if (newPosition instanceof TableChange.First) {
      pendingUpdate.moveFirst(modifyColumnPosition.getOldColumn().getName());
    } else if (newPosition instanceof TableChange.After) {
      TableChange.After after = (TableChange.After) newPosition;
      pendingUpdate.moveAfter(modifyColumnPosition.getOldColumn().getName(), after.column());
    } else {
      throw new UnsupportedOperationException(
          "Cannot apply unknown modify-column-position change: " + modifyColumnPosition);
    }
  }

  private static void applyUniqueConstraint(
      UpdateSchema pendingUpdate, UniqueConstraint constraint) {
    switch (constraint.getType()) {
      case PRIMARY_KEY:
        pendingUpdate.setIdentifierFields(constraint.getColumns());
        break;
      case UNIQUE_KEY:
        throw new UnsupportedOperationException(
            "Unsupported table change: setting unique key constraints.");
      default:
        throw new UnsupportedOperationException(
            "Cannot apply unknown unique constraint: " + constraint.getType().name());
    }
  }
}

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Use PRIMARY KEY instead of UNIQUE KEY in the Flink DDL for Iceberg tables
  2. Remove the unique constraint clause; enforce uniqueness at the application/query level
  3. Note PRIMARY KEY is mapped to Iceberg identifier fields, which do not enforce uniqueness — adjust expectations

Example fix

-- before
ALTER TABLE iceberg_table ADD UNIQUE (order_id);
-- after
ALTER TABLE iceberg_table ADD PRIMARY KEY (order_id) NOT ENFORCED;
Defensive patterns

Strategy: validation

Validate before calling

if (constraint.getType() == UniqueConstraint.Type.UNIQUE_KEY) {
  throw new IllegalArgumentException("Iceberg supports only PRIMARY KEY constraints");
}

Type guard

boolean isPrimaryKeyConstraint(UniqueConstraint c) {
  return c.getType() == UniqueConstraint.Type.PRIMARY_KEY;
}

Try / catch

try {
  FlinkAlterTableUtil.applySchemaChanges(update, List.of(addUnique));
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("unique key constraints")) { /* use PRIMARY KEY instead */ }
  throw e;
}

Prevention

When it happens

Trigger: Running Flink DDL 'ALTER TABLE ... ADD UNIQUE(...) ' or a TableChange.AddUniqueConstraint with constraint type UNIQUE_KEY on an Iceberg table.

Common situations: Generic DDL scripts that declare unique keys for all tables, applied to Iceberg tables where only primary keys (identifier fields) exist.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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