apache/druid · error · IllegalArgumentException
maxValue[ ] must be positive
Error message
maxValue[%s] must be positive
What it means
VSizeColumnarInts.getNumBytesForMax computes how many bytes are needed to store values up to maxValue; a negative maxValue is meaningless for sizing, so it throws IAE immediately. Callers (e.g. numBytes) must pass a non-negative maxValue.
Solutions
- Fix the maxValue computation to initialize at 0 or guard against empty input
- Clamp: pass Math.max(0, maxValue)
- Validate the computed maxValue before calling getNumBytesForMax
Example fix
// before int maxValue = Integer.MIN_VALUE; for (int v : vals) maxValue = Math.min(maxValue, v); // wrong function byte numBytes = VSizeColumnarInts.getNumBytesForMax(maxValue); // after int maxValue = 0; for (int v : vals) maxValue = Math.max(maxValue, v); byte numBytes = VSizeColumnarInts.getNumBytesForMax(maxValue);
Defensive patterns
Strategy: validation
Validate before calling
if (maxValue < 0) throw new IllegalArgumentException("maxValue must be non-negative, got " + maxValue);
byte numBytes = VSizeColumnarInts.getNumBytesForMax(maxValue); Type guard
boolean isValidMaxValue(long v) { return v >= 0 && v <= Integer.MAX_VALUE; } Try / catch
try { numBytes = VSizeColumnarInts.getNumBytesForMax(maxValue); } catch (IAE e) { if (e.getMessage().contains("must be positive")) { maxValue = Math.max(0, maxValue); numBytes = VSizeColumnarInts.getNumBytesForMax(maxValue); } else throw e; } Prevention
- Initialize max accumulators at 0, not Integer.MIN_VALUE
- Guard against empty datasets before computing max
- Name variables carefully to avoid passing minValue instead of maxValue
When it happens
Trigger: Passing a negative maxValue to getNumBytesForMax, typically because maxValue was derived from data containing negatives or from an uninitialized/min-initialized accumulator (e.g. Integer.MIN_VALUE from Math.min over an empty set).
Common situations: Computing max with an initial value of Integer.MIN_VALUE when the dataset is empty, or reusing a minValue instead of maxValue variable.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- integer values must be positive, got
- maxValue[ ] must be positive
- val[ ] > maxValue[ ], please don't lie about maxValue. i[ ]
- A local input source accepts only one of
- A local input source can set parameter
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/4a034fcf183e3d21.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/data/VSizeColumnarInts.java:87
for (int i = 0, size = ints.size(); i < size; i++) {
int val = ints.get(i);
if (val < 0) {
throw new IAE("integer values must be positive, got[%d], i[%d]", val, i);
}
if (val > maxValue) {
throw new IAE("val[%d] > maxValue[%d], please don't lie about maxValue. i[%d]", val, maxValue, i);
}
helperBuffer.putInt(0, val);
buffer.put(helperBuffer.array(), Integer.BYTES - numBytes, numBytes);
}
buffer.position(0);
}
public static byte getNumBytesForMax(int maxValue)
{
if (maxValue < 0) {
throw new IAE("maxValue[%s] must be positive", maxValue);
}
if (maxValue <= 0xFF) {
return 1;
} else if (maxValue <= 0xFFFF) {
return 2;
} else if (maxValue <= 0xFFFFFF) {
return 3;
}
return 4;
}
private final ByteBuffer buffer;
private final int numBytes;
private final int bitsToShift;
private final int size;
View on GitHub (pinned to 9b90983fd2)