apache/beam · error · UnsupportedOperationException
Unsupported Timestamp precision: {precision}
Error message
Unsupported Timestamp precision: {precision} What it means
IcebergUtils.beamFieldTypeToIcebergFieldType maps a Beam Timestamp logical type to Iceberg's TimestampType.withZone() only when its precision argument equals Timestamp.MICROS. Any other precision (e.g. millis) is rejected with UnsupportedOperationException. Iceberg write conversion accepts only microsecond-precision timestamps with zone.
Source
Thrown at sdks/java/io/iceberg/src/main/java/org/apache/beam/sdk/io/iceberg/IcebergUtils.java:232
Schema.LogicalType<?, ?> logicalType = checkArgumentNotNull(beamType.getLogicalType());
if (logicalType instanceof FixedPrecisionNumeric) {
Row args = Preconditions.checkArgumentNotNull(logicalType.getArgument());
Integer precision = Preconditions.checkArgumentNotNull(args.getInt32("precision"));
Integer scale = Preconditions.checkArgumentNotNull(args.getInt32("scale"));
return new TypeAndMaxId(--nestedFieldId, Types.DecimalType.of(precision, scale));
}
if (logicalType instanceof PassThroughLogicalType) {
return beamFieldTypeToIcebergFieldType(logicalType.getBaseType(), nestedFieldId);
}
String logicalTypeIdentifier = logicalType.getIdentifier();
@Nullable Type type = BEAM_LOGICAL_TYPES_TO_ICEBERG_TYPES.get(logicalTypeIdentifier);
if (type == null) {
if (beamType.isLogicalType(Timestamp.IDENTIFIER)) {
int precision = checkStateNotNull(logicalType.getArgument());
if (precision == Timestamp.MICROS.getArgument()) {
type = Types.TimestampType.withZone();
} else {
throw new UnsupportedOperationException(
"Unsupported Timestamp precision: " + precision);
}
} else {
throw new RuntimeException("Unsupported Beam logical type " + logicalTypeIdentifier);
}
}
return new TypeAndMaxId(--nestedFieldId, type);
} else if (beamType.getTypeName().isCollectionType()) { // ARRAY or ITERABLE
Schema.FieldType beamCollectionType =
Preconditions.checkArgumentNotNull(beamType.getCollectionElementType());
// nestedFieldId is reserved for the list's collection type.
// we increment here because further nested fields should use unique ID's
TypeAndMaxId listInfo =
beamFieldTypeToIcebergFieldType(beamCollectionType, nestedFieldId + 1);
Type icebergCollectionType = listInfo.type;
boolean elementTypeIsNullable =View on GitHub (pinned to 12126d8942)
Solutions
- Convert the field to microsecond precision (Timestamp.of(..., MICROS)) before writing.
- Map the value to a supported type such as DateTime with micros precision in the Beam schema.
- Preprocess the Row to convert timestamps to Instant/micros-backed fields.
- If millisecond precision must be preserved, store the value as a LONG epoch field instead.
Example fix
// before
Schema.Field.of("ts", Schema.FieldType.logicalType(Timestamp.of(Timestamp.MILLIS)));
// after
Schema.Field.of("ts", Schema.FieldType.logicalType(Timestamp.of(Timestamp.MICROS))); Defensive patterns
Strategy: validation
Validate before calling
boolean ok = field.getType().isLogicalType(Timestamp.IDENTIFIER)
&& Timestamp.MICROS.getArgument().equals(field.getType().getLogicalType().getArgument()); Try / catch
try {
IcebergUtils.beamRowToIcebergRecord(schema, row);
} catch (UnsupportedOperationException e) {
LOG.error("Timestamp precision not supported: {}", e.getMessage());
} Prevention
- Standardize on Timestamp.MICROS for all timestamp fields written to Iceberg.
- Convert millis-based source timestamps to micros in a preprocessing map.
- Document the precision requirement in pipeline schema definitions.
- Assert field precision in unit tests for sink schemas.
When it happens
Trigger: Writing a Beam schema whose field is a Timestamp logical type with precision != Timestamp.MICROS.getArgument() (e.g. Timestamp.MILLIS) into an Iceberg table — thrown at IcebergUtils.java:232, including nested/list/map element types.
Common situations: PCollections built from sources emitting millisecond timestamps; custom logical types with non-micro precision; converting Avro/other millis-based schemas to Iceberg writes.
Related errors
- micros_instant logical type encountered a Java Instant with
- BigQuery data contained value %s with sub-millisecond precis
- Unexpected timestamp type: {typeName}
- Unrecognized Iceberg Type: {typeId}
- Unsupported Beam logical type {logicalTypeIdentifier}
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/d7ffe832456c60a3.
Report an issue: GitHub.