apache/beam · error · RuntimeException
Unsupported logical type " + field.getType()
Error message
Unsupported logical type " + field.getType()
What it means
During Beam-schema-to-BigQuery-schema conversion, a field whose type is a logical type is looked up in the static LOGICAL_TYPES identifier-to-BigQuery-type map. If the logical type's identifier is not registered there, the converter cannot map it to a BigQuery TableFieldSchema.Type and throws. Only a fixed set of known logical types is supported.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BeamRowToStorageApiProto.java:267
throw new RuntimeException("Unexpected null logical type " + field.getType());
}
@Nullable TableFieldSchema.Type type;
if (logicalType.getIdentifier().equals(Timestamp.IDENTIFIER)) {
int precision =
Preconditions.checkNotNull(
logicalType.getArgument(),
"Expected logical type argument for timestamp precision.");
if (precision != 9) {
throw new RuntimeException(
"Unsupported precision for Timestamp logical type " + precision);
}
// Map Timestamp.NANOS logical type to BigQuery TIMESTAMP(12) for nanosecond precision
type = TableFieldSchema.Type.TIMESTAMP;
builder.setTimestampPrecision(Int64Value.newBuilder().setValue(12L).build());
} else {
type = LOGICAL_TYPES.get(logicalType.getIdentifier());
if (type == null) {
throw new RuntimeException("Unsupported logical type " + field.getType());
}
}
builder = builder.setType(type);
break;
case MAP:
@Nullable FieldType keyType = field.getType().getMapKeyType();
@Nullable FieldType valueType = field.getType().getMapValueType();
if (keyType == null) {
throw new RuntimeException(
"Unexpected null element type for the map's key on " + field.getName());
}
if (valueType == null) {
throw new RuntimeException(
"Unexpected null element type for the map's value on " + field.getName());
}
builder =
builderView on GitHub (pinned to 12126d8942)
Solutions
- Replace the unsupported logical type with a supported one or with its base representation (e.g. use FieldType.STRING or BYTES for custom logical types).
- Register the identifier by adding an entry to LOGICAL_TYPES in BeamRowToStorageApiProto if you build Beam from source.
- Convert the logical type back to its base type before handing the schema to the sink (field.getType().getLogicalType().getBaseType() style re-typing).
- Check whether a newer Beam version maps this logical type; upgrade the google-cloud-platform IO SDK.
Example fix
// before FieldType uuid = FieldType.logicalType(new UuidLogicalType()); // after FieldType uuid = FieldType.string(); // store UUID as STRING
Defensive patterns
Strategy: validation
Validate before calling
for (Schema.Field f : schema.getFields()) {
if (f.getType().getTypeName() == Schema.TypeName.LOGICAL_TYPE) {
String id = f.getType().getLogicalType().getIdentifier();
if (!SUPPORTED_IDS.contains(id)) throw new IllegalArgumentException("Unsupported logical type: " + id);
}
} Type guard
boolean isMappableLogicalType(Schema.FieldType t) {
return t.getTypeName() != Schema.TypeName.LOGICAL_TYPE || t.getLogicalType() != null;
} Try / catch
try {
return BeamRowToStorageApiProto.protoTableSchemaFromBeamSchema(schema);
} catch (RuntimeException e) {
if (e.getMessage().startsWith("Unsupported logical type")) {
return convertWithBaseTypes(schema); // degrade logical types to base types
}
throw e;
} Prevention
- Stick to the documented set of logical types for BigQuery sinks
- Convert custom logical types to STRING/BYTES at source
- Pin and test against a specific Beam version before upgrading
When it happens
Trigger: protoTableSchemaFromBeamSchema/fieldDescriptorFromBeamField encountering FieldType.logicalType(<custom>) whose getIdentifier() is absent from LOGICAL_TYPES, e.g. a user-defined LogicalType, SqlTypes like UUID/Json in versions where they are unmapped, or an Enumeration logical type.
Common situations: Using custom logical types from Beam SQL or application-specific LogicalType implementations with the BigQuery Storage Write sink; upgrading Beam and gaining new logical types not yet mapped by this converter.
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
- Unexpectedly null logical type " + beamFieldType
- Unsupported logical type " + logicalType.getIdentifier()
- Standard logical type '%s' does not have a static of('%s') m
- Error instantiating logical type '%s' with of('%s') method.
- RenameFields does not support renaming logical types.
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/3eff19021f1e6d5b.
Report an issue: GitHub.