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
- Remove the WATERMARK clause from the CREATE TABLE statement; declare watermarks in the Flink job's TableEnvironment/ view instead.
- Create the rowtime/watermark attributes in an intermediate Flink view over the Iceberg table used for streaming reads.
- 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
- Never emit WATERMARK clauses in Iceberg CREATE TABLE
- Declare watermarks in Flink views or the streaming job instead
- Sanitize connector-style DDL templates before applying to Iceberg catalogs
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
- Unsupported table change: AddWatermark.
- Unsupported table change: ModifyWatermark.
- Unsupported table change: DropWatermark.
- Unsupported table change: AddWatermark.
- Unsupported table change: ModifyWatermark.
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/69c7489c24e382af.
Report an issue: GitHub.