apache/beam · error · IllegalArgumentException
Cannot convert Beam logical type: to BigQuery type.
Error message
Cannot convert Beam logical type: to BigQuery type.
What it means
BigQueryUtils.toStandardSQLTypeName converts a Beam Schema FieldType to a BigQuery STANDARD_SQL type name. For logical types it looks up BEAM_TO_BIGQUERY_LOGICAL_MAPPING by the logical type identifier; if not found, it falls back to the PassThroughLogicalType base type, and otherwise throws IllegalArgumentException naming the identifier. It means Beam's schema contained a logical type BigQuery IO doesn't know how to map.
Solutions
- Map the field to a supported base type before writing (e.g. convert the logical type to its underlying primitive via withLogicalType/into base representation)
- Register the logical type as a PassThroughLogicalType so the fallback to its base type kicks in
- Upgrade Beam to the latest version — the BEAM_TO_BIGQUERY_LOGICAL_MAPPING grows over time
- Pre-convert exotic fields to strings/bytes/primitives in a ParDo/Select before the BigQuery sink
Example fix
// before
Schema schema = Schema.builder().addField("id", logicalUUIDType).build(); // unmapped logical type
// after
Schema schema = Schema.builder().addStringField("id").build(); // convert UUID to STRING first
String id = myUuid.getValue().toString(); // drop the logical wrapper before writing Defensive patterns
Strategy: validation
Validate before calling
for (Field f : schema.getFields()) {
if (f.getType().getTypeName() == TypeName.LOGICAL_TYPE) {
LogicalType lt = f.getType().getLogicalType();
if (!(lt instanceof PassThroughLogicalType)) {
throw new IllegalArgumentException("Unmapped logical type for BigQuery: " + lt.getIdentifier());
}
}
} Type guard
boolean bigQueryMappable(FieldType t) {
if (t.getTypeName() != TypeName.LOGICAL_TYPE) return true;
return t.getLogicalType() instanceof PassThroughLogicalType; // plus known mapped identifiers
} Try / catch
try {
rows.apply(BigQueryIO.writeTableRows().to(spec));
} catch (IllegalArgumentException e) {
if (e.getMessage().contains("Cannot convert Beam logical type")) {
// apply a schema transform converting the field to its base type, then retry
} else throw e;
} Prevention
- Convert custom logical types to their base/primitive representation before writing
- Prefer PassThroughLogicalType for passthrough customs so the base-type fallback applies
- Upgrade Beam when using recently added logical types
- Validate pipeline schema against BigQuery-supported types in a unit test
When it happens
Trigger: Writing a PCollection with a Beam schema containing a custom LogicalType (or a logical type added in a newer Beam version, e.g. new type extensions) to BigQuery via BigQueryIO.writeTableRows / getFileLoads / StorageWrite where the type has no mapping and is not a PassThroughLogicalType.
Common situations: Custom user-defined LogicalType registered in the schema; Beam upgrade where new logical types (e.g. new monetary/uuid variants) aren't yet mapped to BigQuery; using Schema-aware transforms with exotic field types like EnumerationLogicalType.
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
- Cannot convert Beam type: to BigQuery type.
- Unexpected null logical type " + field.getType()
- Cannot cast to a compatible object to build ByteString.
- Converting BigQuery type
- Encountered an unsupported type
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/9fb8e344f78b8058.
Report an issue: GitHub.
Appendix: source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/bigquery/BigQueryUtils.java:367
private static final String BIGQUERY_MAP_KEY_FIELD_NAME = "key";
private static final String BIGQUERY_MAP_VALUE_FIELD_NAME = "value";
/**
* Get the corresponding BigQuery {@link StandardSQLTypeName} for supported Beam {@link
* FieldType}.
*/
static StandardSQLTypeName toStandardSQLTypeName(FieldType fieldType) {
StandardSQLTypeName ret;
if (fieldType.getTypeName().isLogicalType()) {
Schema.LogicalType<?, ?> logicalType =
Preconditions.checkArgumentNotNull(fieldType.getLogicalType());
ret = BEAM_TO_BIGQUERY_LOGICAL_MAPPING.get(logicalType.getIdentifier());
if (ret == null) {
if (logicalType instanceof PassThroughLogicalType) {
return toStandardSQLTypeName(logicalType.getBaseType());
}
throw new IllegalArgumentException(
"Cannot convert Beam logical type: "
+ logicalType.getIdentifier()
+ " to BigQuery type.");
}
} else {
ret = BEAM_TO_BIGQUERY_TYPE_MAPPING.get(fieldType.getTypeName());
if (ret == null) {
throw new IllegalArgumentException(
"Cannot convert Beam type: " + fieldType.getTypeName() + " to BigQuery type.");
}
}
return ret;
}
/**
* Represents a timestamp with picosecond precision, split into seconds and picoseconds
* components.
*/View on GitHub (pinned to 12126d8942)