apache/flink · error · TableException

Unsupported map null key handling mode '%s'. Validator shoul

Error message

Unsupported map null key handling mode '%s'. Validator should have checked that.

What it means

TableException from JsonFormatOptionsUtil.getMapNullKeyMode when 'map-null-key.mode' is not fail/drop/literal (compared upper-case after toUpperCase()). It is the same 'validator should have caught it' pattern: the runtime switch only sees an unknown mode when validation was skipped or the enum set drifted between versions.

Source

Thrown at flink-formats/flink-json/src/main/java/org/apache/flink/formats/json/JsonFormatOptionsUtil.java:92

    }

    /**
     * Creates handling mode for null key map data.
     *
     * <p>See {@link #JSON_MAP_NULL_KEY_MODE_FAIL}, {@link #JSON_MAP_NULL_KEY_MODE_DROP}, and {@link
     * #JSON_MAP_NULL_KEY_MODE_LITERAL} for more information.
     */
    public static JsonFormatOptions.MapNullKeyMode getMapNullKeyMode(ReadableConfig config) {
        String mapNullKeyMode = config.get(MAP_NULL_KEY_MODE);
        switch (mapNullKeyMode.toUpperCase()) {
            case JSON_MAP_NULL_KEY_MODE_FAIL:
                return JsonFormatOptions.MapNullKeyMode.FAIL;
            case JSON_MAP_NULL_KEY_MODE_DROP:
                return JsonFormatOptions.MapNullKeyMode.DROP;
            case JSON_MAP_NULL_KEY_MODE_LITERAL:
                return JsonFormatOptions.MapNullKeyMode.LITERAL;
            default:
                throw new TableException(
                        String.format(
                                "Unsupported map null key handling mode '%s'. Validator should have checked that.",
                                mapNullKeyMode));
        }
    }

    // --------------------------------------------------------------------------------------------
    // Validation
    // --------------------------------------------------------------------------------------------

    /** Validator for json decoding format. */
    public static void validateDecodingFormatOptions(ReadableConfig tableOptions) {
        boolean failOnMissingField = tableOptions.get(FAIL_ON_MISSING_FIELD);
        boolean ignoreParseErrors = tableOptions.get(IGNORE_PARSE_ERRORS);
        if (ignoreParseErrors && failOnMissingField) {
            throw new ValidationException(
                    FAIL_ON_MISSING_FIELD.key()
                            + " and "

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Set 'map-null-key.mode' to one of 'FAIL', 'DROP', or 'LITERAL' (any case; it is upper-cased)
  2. Run validateEncodingFormatOptions(tableOptions) before getMapNullKeyMode in custom code
  3. Define the table through DDL so validation happens automatically

Example fix

-- before
'map-null-key.mode' = 'skip'

-- after
'map-null-key.mode' = 'DROP'
Defensive patterns

Strategy: validation

Validate before calling

Set<String> modes = Arrays.stream(MapNullKeyMode.values()).map(Enum::name).collect(Collectors.toSet());
if (!modes.contains(config.get(MAP_NULL_KEY_MODE).toUpperCase())) {
    throw new ValidationException("map-null-key.mode must be FAIL, DROP or LITERAL");
}

Prevention

When it happens

Trigger: Programmatic ReadableConfig usage without validateEncodingFormatOptions; a value like 'FAILS' or 'raise' that upper-cases to none of FAIL/DROP/LITERAL.

Common situations: Custom factories bypassing validation; typos in programmatically-set options; docs/versions mismatch where an old mode name was removed.

Related errors


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