apache/iceberg · error · UnsupportedOperationException
Avro format doesn't support non-string as key type of map…
Error message
Avro format doesn't support non-string as key type of map. The key type is: %s
What it means
extractValueTypeToAvroMap validates the key type of a Flink MAP/MULTISET before building the Avro map schema. Avro maps only allow string keys, so if the key type is not in the CHARACTER_STRING family the converter rejects it. Avro simply cannot represent non-string-keyed maps.
Solutions
- Change the map key type to VARCHAR/CHAR (string) in the table schema.
- Restructure the data as an ARRAY<ROW<key,value>> instead of a non-string-keyed map.
- Cast keys to STRING upstream in the Flink job before writing to the Iceberg table.
- If only a MULTISET is intended, note MULTISET is supported by this method only for string element types; convert non-string multisets to MAP<STRING,INT> or arrays.
Example fix
// before DataTypes.MAP(DataTypes.INT(), DataTypes.STRING()) // after DataTypes.MAP(DataTypes.STRING(), DataTypes.STRING())
Defensive patterns
Strategy: validation
Validate before calling
// Check map key types before conversion
for (Map.Entry<String, LogicalType> e : fieldTypes.entrySet()) {
if (e.getValue() instanceof MapType) {
LogicalType key = ((MapType) e.getValue()).getKeyType();
Preconditions.checkArgument(key.is(LogicalTypeFamily.CHARACTER_STRING),
"Map key must be string: %s", e.getKey());
}
} Type guard
boolean hasStringMapKeys(org.apache.flink.table.types.logical.LogicalType t) {
return !(t instanceof MapType)
|| ((MapType) t).getKeyType().is(LogicalTypeFamily.CHARACTER_STRING);
} Prevention
- Always define MAP columns with VARCHAR/CHAR keys in Flink DDL for Iceberg tables.
- Model non-string-keyed associations as ARRAY<ROW<k,v>> instead of MAP.
- Cast map keys to STRING upstream before writing.
When it happens
Trigger: Converting a Flink table schema containing MAP<INT, T>, MAP<BIGINT, T>, MULTISET<INT> (or any non-VARCHAR/CHAR key) to Avro via AvroSchemaConverter during Iceberg Avro write/serialization.
Common situations: Tables created from SQL with INTEGER-keyed maps or multisets; schemas ingested from sources like Kafka/Protobuf that use integer keys; converting a whole row schema that happens to include such a map.
Understand the failure class
Background: "is not a compatible type" / "cannot merge" errors: when a value's type doesn't match what the library requires — this error's family across 65 libraries.
Related errors
- Avro does not support TIME type with precision: " +…
- Avro does not support TIME type with precision
- Avro does not support TIMESTAMP type with precision: " +…
- Avro format doesn't support non-string as key type of map…
- Unsupported to derive Schema for type
AI-assisted analysis of apache/iceberg@86d9c8fc54 (2026-09-12).
Data as JSON: /api/errors/df161a4bdceca568.
Report an issue: GitHub.
Appendix: source
Thrown at flink/v2.3/flink/src/main/java/org/apache/iceberg/flink/formats/avro/typeutils/AvroSchemaConverter.java:611
throw new UnsupportedOperationException(
"Unsupported to derive Schema for type: " + logicalType);
}
}
public static LogicalType extractValueTypeToAvroMap(LogicalType type) {
LogicalType keyType;
LogicalType valueType;
if (type instanceof MapType) {
MapType mapType = (MapType) type;
keyType = mapType.getKeyType();
valueType = mapType.getValueType();
} else {
MultisetType multisetType = (MultisetType) type;
keyType = multisetType.getElementType();
valueType = new IntType();
}
if (!keyType.is(LogicalTypeFamily.CHARACTER_STRING)) {
throw new UnsupportedOperationException(
"Avro format doesn't support non-string as key type of map. "
+ "The key type is: "
+ keyType.asSummaryString());
}
return valueType;
}
/** Returns schema with nullable true. */
private static Schema nullableSchema(Schema schema) {
return schema.isNullable()
? schema
: Schema.createUnion(SchemaBuilder.builder().nullType(), schema);
}
}
View on GitHub (pinned to 86d9c8fc54)