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

Thrown by JsonToRowDataConverters.createMapConverter when building a converter for a MAP type whose key type is not in the CHARACTER_STRING family. JSON objects can only have string keys, so the Flink JSON deserializer refuses to build a converter for maps like MAP<INT, STRING> on the read path. This fails at converter-construction time, before any record is read.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonToRowDataConverters.java:325

    private JsonToRowDataConverter createArrayConverter(ArrayType arrayType) {
        JsonToRowDataConverter elementConverter = createConverter(arrayType.getElementType());
        final Class<?> elementClass =
                LogicalTypeUtils.toInternalConversionClass(arrayType.getElementType());
        return jsonNode -> {
            final ArrayNode node = (ArrayNode) jsonNode;
            final Object[] array = (Object[]) Array.newInstance(elementClass, node.size());
            for (int i = 0; i < node.size(); i++) {
                final JsonNode innerNode = node.get(i);
                array[i] = elementConverter.convert(innerNode);
            }
            return new GenericArrayData(array);
        };
    }

    private JsonToRowDataConverter 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 JsonToRowDataConverter keyConverter = createConverter(keyType);
        final JsonToRowDataConverter valueConverter = createConverter(valueType);

        return jsonNode -> {
            Iterator<Map.Entry<String, JsonNode>> fields = jsonNode.fields();
            Map<Object, Object> result = new HashMap<>();
            while (fields.hasNext()) {
                Map.Entry<String, JsonNode> entry = fields.next();
                Object key = keyConverter.convert(TextNode.valueOf(entry.getKey()));
                Object value = valueConverter.convert(entry.getValue());
                result.put(key, value);
            }
            return new GenericMapData(result);
        };

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Change the map key type to STRING or VARCHAR in the DDL and cast keys in a downstream operator if numeric keys are needed
  2. Restructure the data as an ARRAY<ROW<key K, value V>> when key order or non-string keys are required
  3. If keys arrive as JSON strings of numbers, keep MAP<STRING, V> and parse keys in a UDF

Example fix

// before
CREATE TABLE t (m MAP<BIGINT, STRING>) WITH ('format'='json', ...);

// after
CREATE TABLE t (m MAP<STRING, STRING>) WITH ('format'='json', ...);
Defensive patterns

Strategy: type-guard

Validate before calling

LogicalType key = mapType.getKeyType();
if (!key.is(LogicalTypeFamily.CHARACTER_STRING)) {
    throw new IllegalArgumentException("JSON format requires string map keys: " + key); // fail at plan time, not job startup
}

Type guard

static boolean isJsonSafeMap(MapType t) {
    return t.getKeyType().is(LogicalTypeFamily.CHARACTER_STRING);
}

Prevention

When it happens

Trigger: Table DDL or derived schema containing MAP with a non-string key (MAP<BIGINT, STRING>, MAP<INT, INT>, keys of TIMESTAMP/BOOLEAN type, etc.) used with 'format'='json' (directly or via a connector such as Kafka). It throws when JsonRowDataDeserializationSchema is instantiated, i.e. at job startup.

Common situations: Hand-written DDL copied from a relational schema where map keys are numeric; converting a map<bigint,...> type from another system into Flink JSON format; using the same schema for JSON and a format (like Avro-ish maps) that permits non-string keys.

Related errors


AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14). Data as JSON: /api/errors/788a72763866e0ce. Report an issue: GitHub.