apache/beam · error · IllegalArgumentException
Unsupported logical type: %s
Error message
Unsupported logical type: %s
What it means
MutationUtils.setBeamValueToMutation() maps Beam Row field values into a Spanner mutation builder, switching on the field's logical type identifier. A logical type with no mapping (ARRAY, MAP, custom logical types, etc.) throws IllegalArgumentException('Unsupported logical type: %s') because Spanner mutations do not accept such values.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/MutationUtils.java:260
// BigDecimal is not nullable
if (decimal == null) {
checkNotNull(decimal, "Null decimal at column %s", columnName);
} else {
mutationBuilder.set(columnName).to(decimal);
}
break;
case LOGICAL_TYPE:
Schema.LogicalType<?, ?> logicalType = checkNotNull(fieldType.getLogicalType());
String identifier = logicalType.getIdentifier();
if (identifier.equals(MicrosInstant.IDENTIFIER)) {
@Nullable Instant instant = row.getValue(columnName);
if (instant == null) {
mutationBuilder.set(columnName).to((Timestamp) null);
} else {
mutationBuilder.set(columnName).to(toSpannerTimestamp(instant));
}
} else {
throw new IllegalArgumentException(
String.format("Unsupported logical type: %s", identifier));
}
break;
case DATETIME:
@Nullable ReadableDateTime dateTime = row.getDateTime(columnName);
if (dateTime == null) {
mutationBuilder.set(columnName).to(((Timestamp) null));
} else {
mutationBuilder
.set(columnName)
.to(Timestamp.ofTimeMicroseconds(dateTime.toInstant().getMillis() * 1000L));
}
break;
case BOOLEAN:
mutationBuilder.set(columnName).to(row.getBoolean(columnName));
break;
case STRING:
mutationBuilder.set(columnName).to(row.getString(columnName));View on GitHub (pinned to 12126d8942)
Solutions
- Map unsupported logical types to supported Spanner types (encode arrays/maps/structs as JSON STRING).
- Flatten nested fields into separate scalar columns before the write.
- If you own a custom LogicalType, add a case for it (or convert to its base type) before writing.
Example fix
// before FieldType listField = FieldType.array(FieldType.string) // unsupported in mutation path // after FieldType listField = FieldType.STRING // store JSON-encoded array
Defensive patterns
Strategy: validation
Validate before calling
for (Field f : row.getSchema().getFields()) {
String id = f.getType().getNullableSupplement().getIdentifier();
if (Set.of("array","map","row","iterable").contains(id.toLowerCase()))
throw new IllegalArgumentException("flatten field before Spanner write: " + f.getName());
} Type guard
boolean isMutationWritable(Field f) { return !f.getType().getTypeName().isCollectionType() && !f.getType().getTypeName().isCompositeType() && !f.getType().getTypeName().isMapType(); } Try / catch
try { mutation = MutationUtils.createMutationFromBeamRows(builder, row); } catch (IllegalArgumentException e) { /* encode field as JSON string and retry */ } Prevention
- Flatten/normalize schemas before Spanner sink
- Encode nested structures as JSON STRING columns
- Keep a mapping test covering every field logical type in your schema
When it happens
Trigger: Writing a Beam Row whose schema contains a field with an unmapped logical type (e.g. array, map, row, or a custom LogicalType) through the Spanner sink's createMutationFromBeamRows path.
Common situations: Auto-generated schemas from sources with nested/repeated fields (e.g. BigQuery RECORD, Avro unions) piped into a Spanner write; adding a new custom LogicalType to the schema without extending MutationUtils.
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
- Unsupported logical type in key: %s
- Unsupported field type: %s
- Cannot provide a coder for a Beam Row. Please provide a sche
- Failed to decode Schema due to an error decoding Field proto
- Encountered UNSPECIFIED AtomicType
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/bb0548266d90df0d.
Report an issue: GitHub.