apache/iceberg · error · UnsupportedOperationException

Unsupported table change: DropConstraint.

Error message

Unsupported table change: DropConstraint.

What it means

FlinkAlterTableUtil.applySchemaChanges does not implement TableChange.DropConstraint, so dropping a constraint through the Flink catalog raises UnsupportedOperationException. Iceberg currently supports setting identifier fields (primary key) but no generic constraint drop.

Source

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

        TableChange.ModifyColumn modifyColumn = (TableChange.ModifyColumn) change;
        applyModifyColumn(pendingUpdate, modifyColumn);
      } else if (change instanceof TableChange.DropColumn) {
        TableChange.DropColumn dropColumn = (TableChange.DropColumn) change;
        pendingUpdate.deleteColumn(dropColumn.getColumnName());
      } else if (change instanceof TableChange.AddWatermark) {
        throw new UnsupportedOperationException("Unsupported table change: AddWatermark.");
      } else if (change instanceof TableChange.ModifyWatermark) {
        throw new UnsupportedOperationException("Unsupported table change: ModifyWatermark.");
      } else if (change instanceof TableChange.DropWatermark) {
        throw new UnsupportedOperationException("Unsupported table change: DropWatermark.");
      } else if (change instanceof TableChange.AddUniqueConstraint) {
        TableChange.AddUniqueConstraint addPk = (TableChange.AddUniqueConstraint) change;
        applyUniqueConstraint(pendingUpdate, addPk.getConstraint());
      } else if (change instanceof TableChange.ModifyUniqueConstraint) {
        TableChange.ModifyUniqueConstraint modifyPk = (TableChange.ModifyUniqueConstraint) change;
        applyUniqueConstraint(pendingUpdate, modifyPk.getNewConstraint());
      } else if (change instanceof TableChange.DropConstraint) {
        throw new UnsupportedOperationException("Unsupported table change: DropConstraint.");
      } else {
        throw new UnsupportedOperationException("Cannot apply unknown table change: " + change);
      }
    }
  }

  private static void applyAddColumn(UpdateSchema pendingUpdate, TableChange.AddColumn addColumn) {
    Column flinkColumn = addColumn.getColumn();
    Preconditions.checkArgument(
        FlinkCompatibilityUtil.isPhysicalColumn(flinkColumn),
        "Unsupported table change: Adding computed column %s.",
        flinkColumn.getName());

    Type icebergType = FlinkSchemaUtil.convert(flinkColumn.getDataType().getLogicalType());

    if (flinkColumn.getDataType().getLogicalType().isNullable()) {
      pendingUpdate.addColumn(
          flinkColumn.getName(), icebergType, flinkColumn.getComment().orElse(null));

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Clear identifier fields via Iceberg API directly: updateSchema().setIdentifierFields("") / rename the identifier field set instead of DROP CONSTRAINT
  2. Drop and recreate the table without the primary key if the identifier fields must be removed
  3. Perform the change with a Spark/Java UpdateSchema against the same table

Example fix

// before (flink sql)
ALTER TABLE iceberg_table DROP PRIMARY KEY;
// after (java)
table.updateSchema().setIdentifierFields("").commit();
Defensive patterns

Strategy: try-catch

Validate before calling

if (changes.stream().anyMatch(c -> c instanceof TableChange.DropConstraint)) {
  throw new IllegalArgumentException("DROP CONSTRAINT is not supported; clear identifier fields via UpdateSchema");
}

Try / catch

try {
  FlinkAlterTableUtil.applySchemaChanges(update, changes);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().contains("DropConstraint")) { /* fall back to updateSchema().setIdentifierFields("") */ }
  throw e;
}

Prevention

When it happens

Trigger: Running 'ALTER TABLE ... DROP PRIMARY KEY/CONSTRAINT <name>' via Flink SQL on an Iceberg table.

Common situations: Trying to remove an identifier-field (primary key) definition from an Iceberg table through Flink DDL.

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