apache/druid · error · IllegalArgumentException
val[ ] > maxValue[ ], please don't lie about maxValue. i[ ]
Error message
val[%d] > maxValue[%d], please don't lie about maxValue. i[%d]
What it means
writeToBuffer checks each value against the maxValue declared when the column was created; a value exceeding maxValue would overflow the chosen byte width, corrupting the packed encoding, so it throws this IAE ('don't lie about maxValue'). The declared maxValue must be a true upper bound of all values.
Solutions
- Compute maxValue by scanning all values before serialization (use a second pass or the fromIterable factory that computes it)
- Increase maxValue to the true maximum and use a byte width that fits it (getNumBytesForMax)
- If the true max can exceed 0xFFFFFFFF constraints, switch to VSizeLongSerde / long-based columns
Example fix
// before: maxValue from partial scan int maxValue = sampledMax; VSizeColumnarInts.fromIndexedInts(values, maxValue); // after: compute true max int maxValue = 0; for (int i = 0; i < values.size(); i++) maxValue = Math.max(maxValue, values.get(i)); VSizeColumnarInts.fromIndexedInts(values, maxValue);
Defensive patterns
Strategy: validation
Validate before calling
int trueMax = 0; for (int i = 0; i < ints.size(); i++) trueMax = Math.max(trueMax, ints.get(i));
if (trueMax > maxValue) throw new IllegalArgumentException("declared maxValue " + maxValue + " < actual " + trueMax); Type guard
boolean fitsMaxValue(IndexedInts ints, int maxValue) { for (int i = 0; i < ints.size(); i++) { if (ints.get(i) > maxValue) return false; } return true; } Try / catch
try { col = VSizeColumnarInts.fromIndexedInts(ints, maxValue); } catch (IAE e) { if (e.getMessage().contains("lie about maxValue")) { maxValue = recomputeMax(ints); col = VSizeColumnarInts.fromIndexedInts(ints, maxValue); } else throw e; } Prevention
- Compute maxValue from the full dataset, never a sample or first pass alone
- Use the fromIterable factory which derives sizing from the data
- Add assertions that declared max >= observed max in encoding utilities
When it happens
Trigger: Calling VSizeColumnarInts.fromIndexedInts with a maxValue smaller than the actual maximum in the IndexedInts — e.g. maxValue computed over a sample rather than the full dataset.
Common situations: Two-pass dictionary encoding where maxValue came from the first pass, streaming ingestion where later rows exceed earlier max, or off-by-one errors when computing maxValue.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- bucketSize must be a power of two but was[%,d]
- bucketSize must be a power of two but was[%,d]
- bucketSize must be a power of two (from 1 up to 128) but…
- integer values must be positive, got
- maxValue[ ] must be positive
AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07).
Data as JSON: /api/errors/aaf8481e29f6aeba.
Report an issue: GitHub.
Appendix: source
Thrown at processing/src/main/java/org/apache/druid/segment/data/VSizeColumnarInts.java:75
{
int numBytes = getNumBytesForMax(maxValue);
final ByteBuffer buffer = ByteBuffer.allocate((ints.size() * numBytes) + (4 - numBytes));
writeToBuffer(buffer, ints, numBytes, maxValue);
return new VSizeColumnarInts(buffer.asReadOnlyBuffer(), numBytes);
}
private static void writeToBuffer(ByteBuffer buffer, IndexedInts ints, int numBytes, int maxValue)
{
ByteBuffer helperBuffer = ByteBuffer.allocate(Integer.BYTES);
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;View on GitHub (pinned to 9b90983fd2)