apache/kafka · error · IllegalArgumentException

keyValue needs to be specified in pairs

Error message

keyValue needs to be specified in pairs

What it means

Thrown by MetricsUtils.getTags(String... keyValue) when the varargs array length is odd. The method pairs consecutive entries as (key, value, key, value, ...) to build an ordered LinkedHashMap of tags; an odd count leaves a dangling key with no value, which the library treats as a programmer error and rejects with IllegalArgumentException.

Source

Thrown at clients/src/main/java/org/apache/kafka/common/metrics/internals/MetricsUtils.java:59

                return timeMs / (60.0 * 1000.0);
            case HOURS:
                return timeMs / (60.0 * 60.0 * 1000.0);
            case DAYS:
                return timeMs / (24.0 * 60.0 * 60.0 * 1000.0);
            default:
                throw new IllegalStateException("Unknown unit: " + unit);
        }
    }

    /**
     * Create a set of tags using the supplied key and value pairs. The order of the tags will be kept.
     *
     * @param keyValue the key and value pairs for the tags; must be an even number
     * @return the map of tags that can be supplied to the {@link Metrics} methods; never null
     */
    public static Map<String, String> getTags(String... keyValue) {
        if ((keyValue.length % 2) != 0)
            throw new IllegalArgumentException("keyValue needs to be specified in pairs");
        Map<String, String> tags = new LinkedHashMap<>(keyValue.length / 2);

        for (int i = 0; i < keyValue.length; i += 2)
            tags.put(keyValue[i], keyValue[i + 1]);
        return tags;
    }
}

View on GitHub (pinned to c31c9215e1)

Solutions

  1. Ensure the getTags(...) call always passes an even number of arguments: every key immediately followed by its value.
  2. When building the array dynamically from a Map, interleave keys and values in iteration and assert the result length is even.
  3. Replace the varargs call with a direct Map.of(...) or LinkedHashMap construction if the pairs are static.
  4. Add a unit test asserting getTags("k","v","k2","v2") returns the expected map to catch regressions.

Example fix

// before
Map<String,String> tags = MetricsUtils.getTags("broker", "1", "client");

// after
Map<String,String> tags = MetricsUtils.getTags("broker", "1", "client", "producer-1");
Defensive patterns

Strategy: validation

Validate before calling

if (keyValue == null || keyValue.length % 2 != 0) {
    throw new IllegalArgumentException("keyValue must be an even-length key/value sequence");
}
Map<String, String> tags = MetricsUtils.getTags(keyValue);

Type guard

static boolean isEvenKeyValuePairs(String[] keyValue) {
    return keyValue != null && keyValue.length % 2 == 0;
}

Prevention

When it happens

Trigger: Calling MetricsUtils.getTags("k1", "v1", "k2") or any invocation where the number of string arguments is not even. Reached wherever tag maps are built from a flat varargs list before constructing a MetricName.

Common situations: A typo or trailing comma in a varargs tag list; dynamically building the tag array from a collection and forgetting the last value; refactor that appended a key without its value; copy-paste of a tag pair with one element dropped.

Related errors


AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03). Data as JSON: /data/errors/0590ab10593f857b.json. Report an issue: GitHub.