apache/beam · error · UnsupportedOperationException
Unexpected Beam type: {}
Error message
Unexpected Beam type: {} What it means
ApplyWatermarkColumn.getInstant switches on the field's Beam primitive type; only a few primitive types are supported for extracting an Instant (via their logical types). If the field's Beam type falls outside all supported cases, the default branch throws UnsupportedOperationException with the unexpected Beam type.
Source
Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/cdc/ApplyWatermarkColumn.java:89
case INT64:
return Instant.ofEpochMilli(timeUnit.toMillis((Long) value));
case DATETIME:
return (Instant) value;
case LOGICAL_TYPE:
String logicalType =
Preconditions.checkStateNotNull(field.getType().getLogicalType()).getIdentifier();
if (logicalType.equals(SqlTypes.DATETIME.getIdentifier())) {
return Instant.ofEpochMilli(
MICROSECONDS.toMillis(DateTimeUtil.microsFromTimestamp((LocalDateTime) value)));
} else if (logicalType.equals(SqlTypes.TIMESTAMP.getIdentifier())
|| logicalType.equals(org.apache.beam.sdk.schemas.logicaltypes.Timestamp.IDENTIFIER)) {
return Instant.ofEpochMilli(
MICROSECONDS.toMillis(DateTimeUtil.microsFromInstant((java.time.Instant) value)));
} else {
throw new UnsupportedOperationException("Unexpected logical type: " + logicalType);
}
default:
throw new UnsupportedOperationException("Unexpected Beam type: " + field.getType());
}
}
@Override
public Duration getAllowedTimestampSkew() {
// Generous skew to cover backfill of historical data and late-arriving CDC patterns.
return Duration.standardDays(365);
}
}
View on GitHub (pinned to 12126d8942)
Solutions
- Point ApplyWatermarkColumn at a field whose Beam type is one of the supported timestamp variants (logical SqlTypes.TIMESTAMP / beam Timestamp).
- Coerce the column in an upstream transform (e.g. parse string timestamps into a proper logical timestamp field).
- Update ApplyWatermarkColumn to support the missing Beam type and rebuild.
- Verify the schema of records at runtime and align the configured watermark field with it.
Example fix
// before
.apply("watermark", ApplyWatermarkColumn.create("event_ts")); // event_ts is STRING
// after
.apply("parse-ts", MapElements.into(SqlTypes.TIMESTAMP).via(s -> Instant.parse(s)))
.apply("watermark", ApplyWatermarkColumn.create("event_ts")); Defensive patterns
Strategy: type-guard
Validate before calling
if (!isSupportedTimestamp(schema.getField(col).getType())) {
throw new IllegalArgumentException("Watermark column is not a timestamp-typed field: " + col);
} Type guard
static boolean isTimestampField(Schema.Field f) {
FieldType t = f.getType();
return t.getTypeName().isNumericType() == false && t.getLogicalType() != null &&
(SqlTypes.TIMESTAMP.getIdentifier().equals(t.getLogicalType().getIdentifier()) ||
org.apache.beam.sdk.schemas.logicaltypes.Timestamp.IDENTIFIER.equals(t.getLogicalType().getIdentifier()));
} Try / catch
try {
records.apply(ApplyWatermarkColumn.create(col));
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unexpected Beam type")) {
throw new IllegalArgumentException("Watermark field must be timestamp-typed, got: " + e.getMessage());
}
throw e;
} Prevention
- Verify the configured watermark column name points at a timestamp field, not a string.
- Parse string timestamps into proper logical timestamp fields upstream.
- Pin schema contracts between producer and pipeline to avoid silent type drift.
When it happens
Trigger: A watermark field typed as a non-timestamp Beam primitive (e.g. STRING, INT64, BOOLEAN, or a nested row/array type) is supplied to ApplyWatermarkColumn, reaching the default branch of the type switch.
Common situations: Misconfigured watermark column name pointing at a string-encoded timestamp, schema drift changing the field type after a connector upgrade, or selecting the wrong column in the CDC record schema.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Unsupported Beam type for Iceberg timestamp with timezone: {
- Unsupported row type: {valueClass}
- Unsupported Iceberg type for Beam type DATETIME: {valueClass
- Unexpected logical type: {}
- Unable to provide coder for %s, this factory can only provid
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/f62c82a4953b5b9a.
Report an issue: GitHub.