apache/seatunnel · error · UnsupportedOperationException
Avro format doesn't support non-string as key type of map. T
Error message
Avro format doesn't support non-string as key type of map. The key type is: ${sqlType} What it means
Avro map schemas require string keys, so when extracting the value type for a MAP field, extractValueTypeToAvroMap() verifies the SeaTunnel map's key type is STRING. Any other key type throws UnsupportedOperationException with this message. Only the value type is returned for the Avro map item schema.
Source
Thrown at seatunnel-connectors-v2/connector-hudi/src/main/java/org/apache/seatunnel/connectors/seatunnel/hudi/sink/convert/AvroSchemaConverter.java:175
Schema array =
SchemaBuilder.builder()
.array()
.items(convertToSchema(arrayType.getElementType(), rowName, true));
return nullableSchema(array);
default:
throw new UnsupportedOperationException(
"Unsupported to derive Schema for type: " + dataType);
}
}
public static SeaTunnelDataType<?> extractValueTypeToAvroMap(SeaTunnelDataType<?> type) {
SeaTunnelDataType<?> keyType;
SeaTunnelDataType<?> valueType;
MapType<?, ?> mapType = (MapType<?, ?>) type;
keyType = mapType.getKeyType();
valueType = mapType.getValueType();
if (keyType.getSqlType() != SqlType.STRING) {
throw new UnsupportedOperationException(
"Avro format doesn't support non-string as key type of map. "
+ "The key type is: "
+ keyType.getSqlType());
}
return valueType;
}
/** Returns schema with nullable true. */
private static Schema nullableSchema(Schema schema) {
return Schema.createUnion(SchemaBuilder.builder().nullType(), schema);
}
private static int computeMinBytesForDecimalPrecision(int precision) {
int numBytes = 1;
while (Math.pow(2.0, 8 * numBytes - 1) < Math.pow(10.0, precision)) {
numBytes += 1;
}
return numBytes;View on GitHub (pinned to cf67b549a7)
Solutions
- Transform the map so its keys are STRING (rebuild the map field with string keys in an upstream transform).
- Serialize the map to a JSON string column before writing to Hudi.
- If key semantics don't matter, drop the field before the sink.
Example fix
// before MapType(INT, STRING) written to Hudi sink // after — convert to string-keyed map (or JSON string) MapType(STRING, STRING) written to Hudi sink
Defensive patterns
Strategy: validation
Validate before calling
schema.toPhysicalRowDataType().getChildren().stream()
.filter(t -> t instanceof MapType)
.map(t -> (MapType<?, ?>) t)
.forEach(m -> {
if (m.getKeyType().getSqlType() != SqlType.STRING)
throw new IllegalArgumentException("map key must be STRING: " + m);
}); Type guard
static boolean hasStringMapKeys(SeaTunnelDataType<?> t) {
return !(t instanceof MapType)
|| ((MapType<?, ?>) t).getKeyType().getSqlType() == SqlType.STRING;
} Try / catch
try {
Schema s = AvroSchemaConverter.convertToSchema(rowType, "rowName");
} catch (UnsupportedOperationException e) {
if (e.getMessage().contains("non-string as key type of map")) {
// rebuild the field with STRING keys or serialize to JSON
} else throw e;
} Prevention
- Enforce STRING map keys in schema design for Hudi sinks.
- Convert non-string-keyed maps at the source/transform layer.
- Add a pre-flight schema check before writing MAP columns to Avro-backed tables.
When it happens
Trigger: A SeaTunnel schema containing a MapType whose keyType's SqlType is not STRING (e.g. MAP<INT,STRING> or MAP<LONG,...>) reaching the Hudi sink schema conversion.
Common situations: Sources with non-string-keyed maps (e.g. Protobuf map<uint32,string>, Parquet/Avro maps with integral keys) fed directly to the Hudi sink; assuming automatic key coercion.
Related errors
- Unsupported to derive Schema for type: ${dataType}
- UNSUPPORTED_DATA_TYPE
- Unsupported type: ${dataType}
- The Avro schema is not a nullable type: ${schema}
- Fail to serialize at field: ${fieldName}.
AI-assisted analysis of apache/seatunnel@cf67b549a7 (2026-09-10).
Data as JSON: /api/errors/216ef2e774f4f6b2.
Report an issue: GitHub.