apache/kafka · error · IllegalArgumentException
Expected minValue >= 0, maxValue >= 0 and maxValue >= minVal
Error message
Expected minValue >= 0, maxValue >= 0 and maxValue >= minValue, but received minValue: %d, maxValue: %d
What it means
Thrown as IllegalArgumentException by the BaseVersionRange constructor when the supplied minValue/maxValue pair violates the invariant minValue >= 0 AND maxValue >= 0 AND maxValue >= minValue. BaseVersionRange (and its subclasses like SupportedVersionRange / FinalizedVersionRange) model negotiated feature versions as non-negative shorts, so a negative value or an inverted range is treated as a programming error rather than a runtime condition. The message echoes both received values to make the violation obvious.
Source
Thrown at clients/src/main/java/org/apache/kafka/common/feature/BaseVersionRange.java:64
// The value of the maximum version.
private final short maxValue;
/**
* Raises an exception unless the following condition is met:
* minValue >= 0 and maxValue >= 0 and maxValue >= minValue.
*
* @param minKeyLabel Label for the min version key, that's used only to convert to/from a map.
* @param minValue The minimum version value.
* @param maxKeyLabel Label for the max version key, that's used only to convert to/from a map.
* @param maxValue The maximum version value.
*
* @throws IllegalArgumentException If any of the following conditions are true:
* - (minValue < 0) OR (maxValue < 0) OR (maxValue < minValue).
* - minKeyLabel is empty, OR, minKeyLabel is empty.
*/
protected BaseVersionRange(String minKeyLabel, short minValue, String maxKeyLabel, short maxValue) {
if (minValue < 0 || maxValue < 0 || maxValue < minValue) {
throw new IllegalArgumentException(
String.format(
"Expected minValue >= 0, maxValue >= 0 and maxValue >= minValue, but received" +
" minValue: %d, maxValue: %d", minValue, maxValue));
}
if (minKeyLabel.isEmpty()) {
throw new IllegalArgumentException("Expected minKeyLabel to be non-empty.");
}
if (maxKeyLabel.isEmpty()) {
throw new IllegalArgumentException("Expected maxKeyLabel to be non-empty.");
}
this.minKeyLabel = minKeyLabel;
this.minValue = minValue;
this.maxKeyLabel = maxKeyLabel;
this.maxValue = maxValue;
}
public short min() {
return minValue;View on GitHub (pinned to c31c9215e1)
Solutions
- Inspect the printed minValue/maxValue pair: if minValue>maxValue, swap them; if either is negative, treat it as missing/unset rather than passing -1.
- Validate at the boundary that converts external input (REST body, metadata record, CLI flag) into a version range, returning a 4xx / deserialization error instead of constructing the object.
- In tests, use the factory methods (e.g. SupportedVersionRange.fromMap) which delegate to the same constructor, so feed them well-formed maps only.
- If the values originate from KRaft metadata, dump the feature record and check whether a prior buggy writer produced the inverted values; recover from a known-good snapshot.
Example fix
// before new SupportedVersionRange((short) 5, (short) 3); // after new SupportedVersionRange((short) 3, (short) 5);
Defensive patterns
Strategy: validation
Validate before calling
short minValue = ..., maxValue = ...;
if (minValue < 0 || maxValue < 0 || maxValue < minValue) {
throw new IllegalArgumentException(
"Invalid version range: minValue=" + minValue + ", maxValue=" + maxValue);
}
// safe to construct the version range now Try / catch
try {
// construct a BaseVersionRange subclass (e.g. SupportedVersionRange)
} catch (IllegalArgumentException e) {
// message starts with "Expected minValue >= 0, maxValue >= 0 and maxValue >= minValue..."
// reject the configuration / negotiated feature and continue with defaults
} Prevention
- Treat version values as unsigned: coerce any parsed value to >= 0 before passing it in
- When reading versions from config/protocol, validate maxValue >= minValue before constructing the range
- Reject negative version values at the parsing boundary rather than at range construction
- Unit-test range construction with (0,0), (min,max), and inverted pairs to catch regressions
When it happens
Trigger: Constructing a BaseVersionRange subclass with minValue<0, maxValue<0, or maxValue<minValue (e.g. new SupportedVersionRange((short)-1, (short)2) or new FinalizedVersionRange((short)5, (short)3)). Also reachable from fromMap() / feature-deserialization paths if a corrupted or hand-crafted metadata map feeds in inverted or negative values.
Common situations: Unit tests of feature negotiation passing sentinel values; a corrupted KRaft metadata record or a forged Features protobuf/map containing negative or inverted version fields; downstream tooling that synthesizes FinalizedVersionRange from user input without validating first.
Related errors
- Expected minKeyLabel to be non-empty.
- Expected maxKeyLabel to be non-empty.
- %s absent in [%s]
- Topic partitions to assign to cannot have null or empty topi
- RebalanceListener cannot be null
AI-assisted analysis of apache/kafka@c31c9215e1 (2026-08-03).
Data as JSON: /data/errors/92ca9ad6ea79b083.json.
Report an issue: GitHub.