apache/iceberg · error · UnsupportedOperationException

Cannot apply unknown unique constraint:

Error message

Cannot apply unknown unique constraint: 

What it means

applyUniqueConstraint exhaustively switches over ConstraintType; if a new or unrecognized constraint type arrives (not PRIMARY_KEY or UNIQUE_KEY), the default branch throws UnsupportedOperationException naming the unknown type. This guards against enum values added by a newer Flink runtime being applied by an older Iceberg Flink module (or vice versa).

Source

Thrown at flink/v1.20/flink/src/main/java/org/apache/iceberg/flink/util/FlinkAlterTableUtil.java:256

      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. Align the iceberg-flink-runtime version with the Flink version in use (e.g. use the flink/vX.Y module matching your Flink major.minor)
  2. Log/inspect constraint.getType().name() to identify the unexpected enum value
  3. Upgrade both Iceberg and Flink together so all ConstraintType values are handled
  4. If you maintain a fork, add a case for the new constraint type or translate it to a supported change

Example fix

// before (version skew)
flink 1.20 + iceberg-flink-runtime-1.19.jar
// after
flink 1.20 + iceberg-flink-runtime-1.20.jar (versions aligned)
Defensive patterns

Strategy: validation

Validate before calling

Set<String> known = Set.of("PRIMARY_KEY", "UNIQUE_KEY");
if (!known.contains(constraint.getType().name())) {
  throw new IllegalStateException("ConstraintType " + constraint.getType().name()
    + " unknown to this iceberg-flink version; check version alignment");
}

Type guard

null

Try / catch

try {
  applySchemaChanges(changes);
} catch (UnsupportedOperationException e) {
  if (e.getMessage().startsWith("Cannot apply unknown unique constraint")) {
    throw new IllegalStateException("Flink/Iceberg version mismatch on ConstraintType; align module versions", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling applySchemaChanges with a UniqueConstraint whose getType() returns an enum constant unknown to this code path — typically after a Flink/Iceberg version mismatch introducing a new ConstraintType.

Common situations: Mixing Iceberg flink-runtime jar version with a different Flink version; custom Catalog implementations feeding synthetic constraints; library upgrades that add enum constants without updating this switch.

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