apache/flink · error · IllegalArgumentException

Map item is not a key-value pair (missing ':'?)

Error message

Map item is not a key-value pair (missing ':'?)

What it means

Thrown when parsing a Map-type config value using the legacy comma/colon-delimited pattern and an entry does not split into exactly two parts on ':'. Each comma-separated item must be 'key:value'. This path is the fallback used when the value is not already a Map object and cannot be parsed as inline YAML.

Source

Thrown at flink-core/src/main/java/org/apache/flink/configuration/ConfigurationUtils.java:463

                Map<Object, Object> map = YamlParserUtils.convertToObject(o.toString(), Map.class);
                return convertToStringMap(map);
            } catch (Exception e) {
                // Fallback to legacy pattern
                return convertToPropertiesWithLegacyPattern(o);
            }
        }
    }

    @Nonnull
    private static Map<String, String> convertToPropertiesWithLegacyPattern(Object o) {
        List<String> listOfRawProperties =
                StructuredOptionsSplitter.splitEscaped(o.toString(), ',');
        return listOfRawProperties.stream()
                .map(s -> StructuredOptionsSplitter.splitEscaped(s, ':'))
                .peek(
                        pair -> {
                            if (pair.size() != 2) {
                                throw new IllegalArgumentException(
                                        "Map item is not a key-value pair (missing ':'?)");
                            }
                        })
                .collect(Collectors.toMap(a -> a.get(0), a -> a.get(1)));
    }

    private static Map<String, String> convertToStringMap(Map<Object, Object> map) {
        return map.entrySet().stream()
                .collect(
                        Collectors.toMap(
                                entry -> convertToString(entry.getKey()),
                                entry -> convertToString(entry.getValue())));
    }

    @SuppressWarnings("unchecked")
    public static <E extends Enum<?>> E convertToEnum(Object o, Class<E> clazz) {
        if (o.getClass().equals(clazz)) {
            return (E) o;

View on GitHub (pinned to 2f3c205e92)

Solutions

  1. Format each map entry as key:value separated by commas, e.g. key1:val1,key2:val2.
  2. Use proper YAML inline-map syntax (curly braces) in flink-conf.yaml: my.map: {key1: val1, key2: val2}.
  3. Escape any literal colon in a value by quoting the value.

Example fix

# before
my.map: a,b

# after
my.map: key1:val1,key2:val2
Defensive patterns

Strategy: validation

Validate before calling

String raw = "key1:val1,key2:val2";
for (String entry : raw.split(",")) {
    if (entry.split(":", -1).length != 2) {
        throw new IllegalArgumentException("Bad map entry: " + entry);
    }
}

Try / catch

try {
    config.set(mapOption, rawValue);
} catch (IllegalArgumentException e) {
    if (e.getMessage().contains("key-value pair")) { /* fix the value */ }
}

Prevention

When it happens

Trigger: Setting a Map<String,String> ConfigOption via a -D flag or flink-conf.yaml with a value like 'a,b' (no colon) or 'a:b:c' (too many colons). The legacy parser is reached when YAML map parsing fails and the raw string is split by StructuredOptionsSplitter on ',' then ':'.

Common situations: Writing map config values as plain comma-separated strings without key:value structure. Accidentally using '=' instead of ':'. Forgetting the colon on a single entry in a multi-entry map.

Related errors


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