apache/beam · error · UnsupportedOperationException
Unsupported Iceberg type for Beam type DATETIME: {valueClass
Error message
Unsupported Iceberg type for Beam type DATETIME: {valueClass} What it means
getBeamDateTimeValue converts an Iceberg value into a Beam joda DateTime for DATETIME columns. It accepts Iceberg LocalDateTime, Long (micros), and String; any other runtime type throws UnsupportedOperationException, indicating the Iceberg value's class is not a recognized datetime representation.
Source
Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergUtils.java:668
break;
default:
throw new UnsupportedOperationException(
"Unsupported Beam type: " + field.getType().getTypeName());
}
}
private static DateTime getBeamDateTimeValue(Object icebergValue) {
long micros;
if (icebergValue instanceof OffsetDateTime) {
micros = DateTimeUtil.microsFromTimestamptz((OffsetDateTime) icebergValue);
} else if (icebergValue instanceof LocalDateTime) {
micros = DateTimeUtil.microsFromTimestamp((LocalDateTime) icebergValue);
} else if (icebergValue instanceof Long) {
micros = (long) icebergValue;
} else if (icebergValue instanceof String) {
return DateTime.parse((String) icebergValue);
} else {
throw new UnsupportedOperationException(
"Unsupported Iceberg type for Beam type DATETIME: " + icebergValue.getClass());
}
return new DateTime(micros / 1000L);
}
private static Object getLogicalTypeValue(Object icebergValue, Schema.FieldType type) {
if (icebergValue instanceof String) {
String strValue = (String) icebergValue;
if (type.isLogicalType(SqlTypes.DATE.getIdentifier())) {
return LocalDate.parse(strValue);
} else if (type.isLogicalType(SqlTypes.TIME.getIdentifier())) {
return LocalTime.parse(strValue);
} else if (type.isLogicalType(SqlTypes.DATETIME.getIdentifier())) {
return LocalDateTime.parse(strValue);
} else if (type.isLogicalType(Timestamp.IDENTIFIER)) {
return OffsetDateTime.parse(strValue).toInstant();
}
} else if (icebergValue instanceof Long) {View on GitHub (pinned to 12126d8942)
Solutions
- Map timestamptz columns to a Beam field whose value conversion accepts OffsetDateTime, or pre-convert: OffsetDateTime -> LocalDateTime via toLocalDateTime()/toInstant().toEpochMilli()*1000
- If you get a java.sql.Timestamp or java.util.Date, convert first: Timestamp.toLocalDateTime() or date.getTime()*1000 for micros
- Verify which Iceberg runtime/reader produced the value and normalize at ingestion
- Wrap conversion with a small adapter function that normalizes known classes to the accepted three before calling the IO
Example fix
// before Object v = offsetDateTimeValue; // java.time.OffsetDateTime // after Object v = offsetDateTimeValue.toInstant().toEpochMilli() * 1000L; // micros Long
Defensive patterns
Strategy: type-guard
Validate before calling
if (!(v instanceof java.time.LocalDateTime) && !(v instanceof Long) && !(v instanceof String)) {
throw new IllegalArgumentException("DATETIME field value must be LocalDateTime/Long/String, got " + v.getClass());
} Type guard
boolean isBeamDatetimeCompatible(Object v) {
return v instanceof java.time.LocalDateTime || v instanceof Long || v instanceof String;
} Try / catch
try {
row = structToRow(schema, struct);
} catch (UnsupportedOperationException e) {
if (e.getMessage().startsWith("Unsupported Iceberg type for Beam type DATETIME")) {
// convert OffsetDateTime/Date to micros and retry
} else { throw e; }
} Prevention
- Map timestamptz columns to fields the converter supports, or pre-convert OffsetDateTime to micros
- Normalize datetime values at pipeline ingestion
- Test read paths against the exact Iceberg reader implementation in use
When it happens
Trigger: structToRow/addIcebergValue converts a DATETIME Beam field whose Iceberg value is not LocalDateTime, Long, or String — e.g. java.time.OffsetDateTime from a timestamptz column mapped onto a DATETIME field, an Iceberg Timestamp value object, or a BigDecimal/byte[] from a custom deserializer.
Common situations: Mapping a timestamptz Iceberg column to a non-nullable DATETIME Beam field where the reader returned OffsetDateTime; custom Iceberg object models returning different classes; mixing read paths (avro-based vs internal) with different representations.
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}
- Unexpected Beam type: {}
- Unable to provide coder for %s, this factory can only provid
- The input schema must have exactly one field of type byte.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/854871d9885cc409.
Report an issue: GitHub.