apache/beam · error · IllegalArgumentException
Unsupported logical type " + logicalType.getName()
Error message
Unsupported logical type " + logicalType.getName()
What it means
scalarToProtoValue looks up an encoder for a field's Avro logical type in LOGICAL_TYPE_ENCODERS. If a logical type is present but has no registered encoder (e.g. unknown or custom named logical types like "decimal-metadata" or user-defined logical types), it throws IllegalArgumentException("Unsupported logical type ..."). Only a fixed set of logical types (timestamp, date, time, decimal) is supported.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/AvroGenericRecordToStorageApiProto.java:569
// Handle negative timestamps (before epoch)
if (nanos < 0 && nanoAdjustment != 0) {
seconds -= 1;
nanoAdjustment += NANOS_PER_SECOND;
}
long picoseconds = nanoAdjustment * PICOS_PER_NANO;
return buildTimestampPicosMessage(
Preconditions.checkNotNull(descriptor).getMessageType(), seconds, picoseconds);
}
LogicalType logicalType = LogicalTypes.fromSchema(type.getType());
if (logicalType != null) {
@Nullable
BiFunction<LogicalType, Object, Object> logicalTypeEncoder =
LOGICAL_TYPE_ENCODERS.get(logicalType.getName());
if (logicalTypeEncoder == null) {
throw new IllegalArgumentException("Unsupported logical type " + logicalType.getName());
}
return logicalTypeEncoder.apply(logicalType, value);
} else {
@Nullable Function<Object, Object> encoder = PRIMITIVE_ENCODERS.get(type.getType().getType());
if (encoder == null) {
throw new RuntimeException("Unexpected beam type " + fieldSchema);
}
return encoder.apply(value);
}
}
}
View on GitHub (pinned to 12126d8942)
Solutions
- Remove or flatten the unsupported logical type from the Avro schema (use the underlying primitive type)
- Pre-convert the value to a supported type (e.g. convert custom logical types to long/string) before writing
- Check the supported encoder keys in AvroGenericRecordToStorageApiProto.LOGICAL_TYPE_ENCODERS and match your logical type name to one
- Upgrade Beam — newer versions add support for more logical types
Example fix
// before Schema uuidField = LogicalTypes.uuid().addToSchema(Schema.create(Schema.Type.STRING)); // after Schema uuidField = Schema.create(Schema.Type.STRING); // plain string
Defensive patterns
Strategy: validation
Validate before calling
// Java
Schema logicalTypeSchema = schema.getField(name).schema();
LogicalType lt = logicalTypeSchema.getLogicalType();
if (lt != null && !Set.of("timestamp-millis","timestamp-micros","date","time-millis","time-micros","decimal").contains(lt.getName())) {
throw new IllegalStateException("Unsupported logical type: " + lt.getName());
} Type guard
// Java
BiFunction<LogicalType, Object, Object> enc = LOGICAL_TYPE_ENCODERS.get(lt.getName());
if (enc != null) { /* supported */ } Try / catch
// Java
try {
return scalarToProtoValue(fieldSchema, type, value);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Unsupported logical type")) {
// fall back to primitive conversion or skip field
}
throw e;
} Prevention
- Restrict Avro logical types in your schemas to Beam's supported set
- Flatten custom logical types to primitives before writing to BigQuery
- Check LOGICAL_TYPE_ENCODERS keys in the Beam version you deploy
When it happens
Trigger: Writing Avro GenericRecords with a field whose schema has a logicalType not in LOGICAL_TYPE_ENCODERS (e.g. custom logical types, uuid, duration) to BigQuery via Storage API
Common situations: Avro schemas generated by tools that attach custom logical types (Confluent schema registry, Avro 1.9+ logical types like uuid), or decimal logical types with unsupported precision/scale combos.
Related errors
- Unknown logical type
- Unknown logical type " + identifier
- Reserved field name <field.name()> in user schema.
- Unsupported type <elementType.getType()>
- Received null value for non-nullable field " + fieldDescript
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/8324353651567cf0.
Report an issue: GitHub.