apache/beam · error · RuntimeException
Unsupported spanner type %s for column %s.
Error message
Unsupported spanner type %s for column %s.
What it means
getStructValue reads a single column of a Spanner Struct into a Beam Row value. When the column's Spanner TypeCode has no case in the switch (an unrecognized or unmapped type), this RuntimeException names both the type code and the column. Unlike the IllegalArgumentException guards, this is a RuntimeException, typically signaling a schema/type the SDK version does not know.
Source
Thrown at sdks/java/io/google-cloud-platform/src/main/java/org/apache/beam/sdk/io/gcp/spanner/StructUtils.java:411
return struct.getFloat(column);
case FLOAT64:
return struct.getDouble(column);
case NUMERIC:
return struct.getBigDecimal(column);
case STRING:
return struct.getString(column);
case ARRAY:
return getStructArrayValue(
struct, struct.getColumnType(column).getArrayElementType(), field);
case STRUCT:
@Nullable Schema schema = field.getType().getRowSchema();
if (schema == null) {
throw new NullPointerException("Null schema at field " + field.getName());
} else {
return structToBeamRow(struct.getStruct(column), schema);
}
default:
throw new RuntimeException(
String.format("Unsupported spanner type %s for column %s.", typeCode, column));
}
}
private static @Nullable Object getStructArrayValue(
Struct struct, Type arrayType, Schema.Field field) {
Type.Code arrayCode = arrayType.getCode();
String column = field.getName();
if (struct.isNull(column)) {
return null;
}
switch (arrayCode) {
case BOOL:
return struct.getBooleanList(column);
case BYTES:
return struct.getBytesList(column);
case TIMESTAMP:
// Check if expects MicrosInstant in arraysView on GitHub (pinned to 12126d8942)
Solutions
- Upgrade the Beam Google Cloud Platform SDK so the Spanner TypeCode is mapped.
- Change the query to cast the column to a supported type (e.g. CAST(col AS STRING)).
- Wrap the read in try-catch for RuntimeException and produce a diagnostic schema dump to identify the offending column.
Example fix
// before SELECT id, user_profile FROM users -- user_profile is JSON type // after SELECT id, TO_JSON_STRING(user_profile) AS user_profile FROM users
Defensive patterns
Strategy: try-catch
Try / catch
try {
Row row = StructUtils.structToBeamRow(struct, schema);
} catch (RuntimeException e) {
LOG.error("Failed to convert Spanner row: {}", e.getMessage());
throw new IOException("Unsupported Spanner column type encountered; upgrade SDK or cast in query", e);
} Prevention
- Cast unsupported column types (JSON/PROTO) to STRING in read queries.
- Upgrade the Beam SDK when adopting new Spanner column types.
- Test reads against production-like schemas in CI.
When it happens
Trigger: Reading Spanner rows (structValues -> getStructValue) where a column's TypeCode is not one of the mapped codes (e.g. newer Spanner types like JSON/PROTO or unmapped codes) at read time.
Common situations: Spanner databases using newer column types with an older Beam SDK; queries returning exotic expressions whose inferred type is unmapped.
Related errors
- Unsupported type '%s'.
- Unexpected type {}
- Unexpected type {}
- Field type%s %s not supported when converting between JSON a
- char type not supported yet (https://github.com/apache/beam/
AI-assisted analysis of apache/beam@12126d8942 (2026-09-13).
Data as JSON: /api/errors/427eece57c8b40d0.
Report an issue: GitHub.