apache/iceberg · error · UnsupportedOperationException

Creating table with watermark specs is not supported yet.

Error message

Creating table with watermark specs is not supported yet.

What it means

Guard in FlinkCatalog.validateFlinkTable (reached from create/alter paths): the Flink table schema includes watermark specs, which Iceberg tables cannot store or enforce. Validation happens before any catalog mutation, so no partial table state is created.

Source

Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/FlinkCatalog.java:639

  }

  private static void validateFlinkTable(CatalogBaseTable table) {
    Preconditions.checkArgument(
        table instanceof CatalogTable, "The Table should be a CatalogTable.");

    org.apache.flink.table.api.Schema schema = table.getUnresolvedSchema();
    schema
        .getColumns()
        .forEach(
            column -> {
              if (!FlinkCompatibilityUtil.isPhysicalColumn(column)) {
                throw new UnsupportedOperationException(
                    "Creating table with computed columns is not supported yet.");
              }
            });

    if (!schema.getWatermarkSpecs().isEmpty()) {
      throw new UnsupportedOperationException(
          "Creating table with watermark specs is not supported yet.");
    }
  }

  private static PartitionSpec toPartitionSpec(List<String> partitionKeys, Schema icebergSchema) {
    PartitionSpec.Builder builder = PartitionSpec.builderFor(icebergSchema);
    partitionKeys.forEach(builder::identity);
    return builder.build();
  }

  private static List<String> toPartitionKeys(PartitionSpec spec, Schema icebergSchema) {
    ImmutableList.Builder<String> partitionKeysBuilder = ImmutableList.builder();
    for (PartitionField field : spec.fields()) {
      if (field.transform().isIdentity()) {
        partitionKeysBuilder.add(icebergSchema.findColumnName(field.sourceId()));
      } else {
        // Not created by Flink SQL.
        // For compatibility with iceberg tables, return empty.

View on GitHub (pinned to 86d9c8fc54)

Solutions

  1. Remove the WATERMARK clause from the CREATE TABLE statement; declare watermarks in the Flink job's TableEnvironment/ view instead.
  2. Create the rowtime/watermark attributes in an intermediate Flink view over the Iceberg table used for streaming reads.
  3. Keep the Iceberg DDL limited to physical columns.

Example fix

// before
CREATE TABLE t (id BIGINT, ts TIMESTAMP(3), WATERMARK FOR ts AS ts - INTERVAL '5' SECOND);
// after
CREATE TABLE t (id BIGINT, ts TIMESTAMP(3));
-- apply WATERMARK in a view: CREATE VIEW v AS SELECT * FROM t;
-- then declare watermark on the view schema in the job
Defensive patterns

Strategy: validation

Validate before calling

if (!table.getUnresolvedSchema().getWatermarkSpecs().isEmpty()) { /* strip watermarks before create */ }

Prevention

When it happens

Trigger: CREATE TABLE ... WATERMARK FOR rowtime_column AS <expression> processed through createIcebergTable or alterTable.

Common situations: Defining a source-table schema with event-time watermarks and pointing it at the Iceberg catalog; copying Kafka connector DDL (where WATERMARK is common) into Iceberg table creation; template DDL generators that always emit watermark clauses.

Related errors


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