{"record":{"id":"30f3f7d1bd783970","repo":"apache/druid","slug":"integer-values-must-be-positive-got-d-i-d","errorCode":null,"errorMessage":"integer values must be positive, got[%d], i[%d]","messagePattern":"integer values must be positive, got\\[(.+?)\\], i\\[(.+?)\\]","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/data/VSizeColumnarInts.java","lineNumber":72,"sourceCode":"  }\n\n  public static VSizeColumnarInts fromIndexedInts(IndexedInts ints, int maxValue)\n  {\n    int numBytes = getNumBytesForMax(maxValue);\n\n    final ByteBuffer buffer = ByteBuffer.allocate((ints.size() * numBytes) + (4 - numBytes));\n    writeToBuffer(buffer, ints, numBytes, maxValue);\n\n    return new VSizeColumnarInts(buffer.asReadOnlyBuffer(), numBytes);\n  }\n\n  private static void writeToBuffer(ByteBuffer buffer, IndexedInts ints, int numBytes, int maxValue)\n  {\n    ByteBuffer helperBuffer = ByteBuffer.allocate(Integer.BYTES);\n    for (int i = 0, size = ints.size(); i < size; i++) {\n      int val = ints.get(i);\n      if (val < 0) {\n        throw new IAE(\"integer values must be positive, got[%d], i[%d]\", val, i);\n      }\n      if (val > maxValue) {\n        throw new IAE(\"val[%d] > maxValue[%d], please don't lie about maxValue.  i[%d]\", val, maxValue, i);\n      }\n\n      helperBuffer.putInt(0, val);\n      buffer.put(helperBuffer.array(), Integer.BYTES - numBytes, numBytes);\n    }\n    buffer.position(0);\n  }\n\n  public static byte getNumBytesForMax(int maxValue)\n  {\n    if (maxValue < 0) {\n      throw new IAE(\"maxValue[%s] must be positive\", maxValue);\n    }\n\n    if (maxValue <= 0xFF) {","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/data/VSizeColumnarInts.java#L54-L90","documentation":"VSizeColumnarInts.writeToBuffer validates every value before packing it into a variable-width buffer; negative integers cannot be encoded, so any val < 0 throws this IAE naming the offending value and its index. It is a data-validation guard during column serialization (via fromIndexedInts).","triggerScenarios":"Calling VSizeColumnarInts.fromIndexedInts (or dimension serialization) with an IndexedInts containing a negative int, e.g. from a dictionary lookup returning -1 or a broken aggregator.","commonSituations":"Ingestion of numeric dimension values where a sentinel -1 or missing-value marker was not translated, custom aggregators producing negative dictionary ids, or integer underflow in upstream transforms.","solutions":["Sanitize input data so values are non-negative before building the column (clamp or map sentinels to 0/null)","Fix the upstream producer (aggregator/expression) that emits negative values","If negatives are legitimate, use a column type that supports signed values instead of VSizeColumnarInts"],"exampleFix":"// before\nVSizeColumnarInts.fromIndexedInts(rawInts, maxValue);\n// after\nfor (int i = 0; i < rawInts.size(); i++) { if (rawInts.get(i) < 0) throw new IllegalArgumentException(\"negative at \" + i); }\nVSizeColumnarInts.fromIndexedInts(rawInts, maxValue);","handlingStrategy":"validation","validationCode":"for (int i = 0, size = ints.size(); i < size; i++) { if (ints.get(i) < 0) throw new IllegalArgumentException(\"negative value at index \" + i); }","typeGuard":"boolean isNonNegative(IndexedInts ints) { for (int i = 0; i < ints.size(); i++) { if (ints.get(i) < 0) return false; } return true; }","tryCatchPattern":"try { col = VSizeColumnarInts.fromIndexedInts(ints, maxValue); } catch (IAE e) { if (e.getMessage().contains(\"must be positive\")) { log.error(\"negative value in column data\"); } throw e; }","preventionTips":["Sanitize numeric dimensions before ingestion so sentinels like -1 become null/0","Unit-test aggregators for negative outputs","Prefer signed-capable column types when negatives are legitimate"],"tags":["serialization","validation","integers"],"backgroundTag":"invalid-argument-value","analyzedSha":"9b90983fd291f26935af934383ce360473179e4d","analyzedAt":"2026-09-07T13:32:30.957Z","contentChangedAt":"2026-09-07T13:32:30.957Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}