apache/flink · error · java.lang.UnsupportedOperationException
JSON format doesn't support non-string as key type of map. T
Error message
JSON format doesn't support non-string as key type of map. The type is: {} What it means
UnsupportedOperationException from createMapConverter when the map key type is not in the CHARACTER_STRING family. JSON object keys are always strings, so a MAP<INT, ...> or MAP<BIGINT, ...> column cannot be populated from JSON and the converter refuses to be created (fail-fast at schema build, before any record is read).
Source
Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonParserToRowDataConverters.java:369
LogicalTypeUtils.toInternalConversionClass(arrayType.getElementType());
return jp -> {
if (jp.currentToken() != JsonToken.START_ARRAY) {
throw new IllegalStateException("Illegal JSON array data...");
}
List<Object> result = new ArrayList<>();
while (jp.nextToken() != JsonToken.END_ARRAY) {
Object convertField = elementConverter.convert(jp);
result.add(convertField);
}
final Object[] array = (Object[]) Array.newInstance(elementClass, result.size());
return new GenericArrayData(result.toArray(array));
};
}
private JsonParserToRowDataConverter createMapConverter(
String typeSummary, LogicalType keyType, LogicalType valueType) {
if (!keyType.is(LogicalTypeFamily.CHARACTER_STRING)) {
throw new UnsupportedOperationException(
"JSON format doesn't support non-string as key type of map. "
+ "The type is: "
+ typeSummary);
}
final JsonParserToRowDataConverter keyConverter = createConverter(keyType);
final JsonParserToRowDataConverter valueConverter = createConverter(valueType);
return jp -> {
if (jp.currentToken() != JsonToken.START_OBJECT) {
throw new IllegalStateException("Illegal JSON map data...");
}
Map<Object, Object> result = new HashMap<>();
while (jp.nextToken() != JsonToken.END_OBJECT) {
Object key = keyConverter.convert(jp);
jp.nextToken();
Object value = valueConverter.convert(jp);
result.put(key, value);
}View on GitHub (pinned to 2f3c205e92)
Solutions
- Change the key type to STRING: MAP<STRING, T> and cast keys downstream (CAST or a UDF) if numeric semantics are needed
- Or restructure the data as an ARRAY<ROW<key T, value U>>
- For lookups by typed key, normalize keys to strings at the producer
Example fix
-- before ids MAP<BIGINT, STRING> -- after ids MAP<STRING, STRING>
Defensive patterns
Strategy: validation
Validate before calling
if (!mapType.getKeyType().is(LogicalTypeFamily.CHARACTER_STRING)) {
throw new UnsupportedOperationException("Use MAP<STRING, ...> for JSON");
} Prevention
- Always declare JSON map keys as STRING and cast downstream
- For typed keys, model as ARRAY<ROW<key, value>> instead
When it happens
Trigger: DDL declaring MAP<INT, T> / MAP<BIGINT, T> / MAP<DATE, T> etc. for a JSON table using the parser-based deserializer; also MAP<STRING,...> is fine, MAP with any non-string key type is not.
Common situations: Porting a schema from a format that allows typed keys (Avro maps always have string keys, but Parquet/Row-based tools may suggest typed ones); auto-derived schemas producing numeric keys.
Related errors
- Unsupported type: {}
- Unsupported map null key handling mode '%s'. Validator shoul
- Unsupported value '%s' for option %s. Supported values are %
- Numeric value (%s) out of range of Java byte.
- Illegal JSON map data...
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/46ae3b5fdbc9333f.
Report an issue: GitHub.