apache/beam · error · RuntimeException
Unhandled logical type ${identifier}
Error message
Unhandled logical type ${identifier} What it means
During Beam FieldType -> Avro schema conversion, the FieldType carries a logical type whose identifier is not handled by the converter (only Timestamp-related identifiers are supported in that switch). The library throws RuntimeException because it cannot map the logical type to any Avro representation.
Source
Thrown at sdks/java/extensions/avro/src/main/java/org/apache/beam/sdk/extensions/avro/schemas/utils/AvroUtils.java:1235
.addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT));
} else if ("TIME".equals(identifier)) {
baseType =
LogicalTypes.timeMillis()
.addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.INT));
} else if (SqlTypes.TIMESTAMP.getIdentifier().equals(identifier)) {
baseType =
LogicalTypes.timestampMicros()
.addToSchema(org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG));
} else if (Timestamp.IDENTIFIER.equals(identifier)) {
int precision = checkNotNull(logicalType.getArgument());
if (precision != 9) {
throw new RuntimeException(
"Timestamp logical type precision not supported:" + precision);
}
baseType = org.apache.avro.Schema.create(org.apache.avro.Schema.Type.LONG);
baseType.addProp("logicalType", TIMESTAMP_NANOS_LOGICAL_TYPE);
} else {
throw new RuntimeException(
"Unhandled logical type " + checkNotNull(fieldType.getLogicalType()).getIdentifier());
}
break;
case ARRAY:
case ITERABLE:
baseType =
org.apache.avro.Schema.createArray(
getFieldSchema(
checkNotNull(fieldType.getCollectionElementType()), fieldName, namespace));
break;
case MAP:
if (checkNotNull(fieldType.getMapKeyType()).getTypeName().isStringType()) {
// Avro only supports string keys in maps.
baseType =
org.apache.avro.Schema.createMap(
getFieldSchema(checkNotNull(fieldType.getMapValueType()), fieldName, namespace));View on GitHub (pinned to 12126d8942)
Solutions
- Remove or replace the unsupported logical type on the FieldType before conversion.
- Implement a mapping yourself by converting the field to its base type and attaching the Avro logical-type prop manually.
- Register/extend the converter (or upstream a case for the identifier) if the logical type is broadly useful.
- Catch RuntimeException around schema conversion and fall back to the field's underlying primitive type.
Example fix
// before
Field.of("status", FieldType.string().withLogicalType(new MyCustomLogicalType()))
// after
Field.of("status", FieldType.string()) // drop unsupported logical type before toAvroSchema Defensive patterns
Strategy: validation
Validate before calling
boolean hasSupportedLogicalType(FieldType ft) {
LogicalType lt = ft.getLogicalType();
return lt == null || SUPPORTED_IDENTIFIERS.contains(lt.getIdentifier()); // e.g. Timestamp variants only
} Try / catch
try {
org.apache.avro.Schema s = AvroUtils.toAvroSchema(rowSchema);
} catch (RuntimeException e) {
if (e.getMessage() != null && e.getMessage().startsWith("Unhandled logical type ")) {
org.apache.avro.Schema s2 = AvroUtils.toAvroSchema(stripLogicalTypes(rowSchema));
} else { throw e; }
} Prevention
- Avoid custom LogicalType implementations on fields destined for Avro sinks.
- Strip or document unsupported logical types during schema ingestion.
- Keep the Beam Avro extension up to date with the Beam SDK core.
- Unit-test schema conversion for every production schema.
When it happens
Trigger: Calling AvroUtils.getFieldSchema/toAvroSchema with a FieldType whose getLogicalType() has an identifier other than the supported Timestamp variants (e.g. custom LogicalType implementations, Enumeration, FixedBytes-adjacent logical types depending on branch).
Common situations: Custom LogicalType subclasses registered on Beam schemas; schemas ported from other frameworks with unsupported logical annotations; upgrading Beam and passing logical types the Avro converter never implemented.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- Can't convert 'null' to FieldType
- Timestamp logical type precision not supported:${precision}
- Avro only supports maps with string keys
- Unexpected type ${fieldType}
- Can't convert 'null' to non-nullable field
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9867cd8966a47628.
Report an issue: GitHub.