{"record":{"id":"d3cb67b24b3d5399","repo":"apache/druid","slug":"bucketsize-must-be-a-power-of-two-from-1-up-to-12-d3cb67","errorCode":null,"errorMessage":"bucketSize must be a power of two (from 1 up to 128) but was[%,d]","messagePattern":"bucketSize must be a power of two \\(from 1 up to 128\\) but was\\[%,d\\]","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"processing/src/main/java/org/apache/druid/segment/data/FrontCodedIntArrayIndexedWriter.java","lineNumber":96,"sourceCode":"  private WriteOutBytes valuesOut = null;\n  private int numWritten = 0;\n  private ByteBuffer scratch;\n  private int logScratchSize = 10;\n  private boolean isClosed = false;\n  private boolean hasNulls = false;\n\n  private int readCachedBucket = -1;\n  @Nullable\n  private ByteBuffer readBufferCache = null;\n\n  public FrontCodedIntArrayIndexedWriter(\n      SegmentWriteOutMedium segmentWriteOutMedium,\n      ByteOrder byteOrder,\n      int bucketSize\n  )\n  {\n    if (Integer.bitCount(bucketSize) != 1 || bucketSize < 1 || bucketSize > 128) {\n      throw new IAE(\"bucketSize must be a power of two (from 1 up to 128) but was[%,d]\", bucketSize);\n    }\n    this.segmentWriteOutMedium = segmentWriteOutMedium;\n    this.scratch = ByteBuffer.allocate(1 << logScratchSize).order(byteOrder);\n    this.bucketSize = bucketSize;\n    this.byteOrder = byteOrder;\n    this.bucketBuffer = new int[bucketSize][];\n    this.getOffsetBuffer = ByteBuffer.allocate(Integer.BYTES).order(byteOrder);\n    this.div = Integer.numberOfTrailingZeros(bucketSize);\n  }\n\n  @Override\n  public void open() throws IOException\n  {\n    headerOut = segmentWriteOutMedium.makeWriteOutBytes();\n    valuesOut = segmentWriteOutMedium.makeWriteOutBytes();\n  }\n\n  @Override","sourceCodeStart":78,"sourceCodeEnd":114,"githubUrl":"https://github.com/apache/druid/blob/9b90983fd291f26935af934383ce360473179e4d/processing/src/main/java/org/apache/druid/segment/data/FrontCodedIntArrayIndexedWriter.java#L78-L114","documentation":"FrontCodedIntArrayIndexedWriter requires the bucketSize used for front-coding int arrays to be a power of two between 1 and 128 inclusive. The constructor validates Integer.bitCount(bucketSize)==1 (single bit set) and range before allocating the bucket buffer, throwing IAE otherwise. Bucket size drives the front-coding block layout, so non-power-of-two or oversized values cannot be represented.","triggerScenarios":"Calling new FrontCodedIntArrayIndexedWriter(medium, byteOrder, bucketSize) with bucketSize = 0, negative, > 128, or any value that is not a power of two (e.g. 3, 6, 100, 129).","commonSituations":"A user-supplied 'frontCodedArrayBucketSize' segment or column config typo (e.g. 100 instead of 128), computed bucket sizes from heuristics that don't round to powers of two, or off-by-one (0 or 129).","solutions":["Set bucketSize to a power of two in [1,128]: 1, 2, 4, 8, ..., 128 (e.g. 128).","Round user config to the nearest valid power of two before constructing: bucketSize = Integer.highestOneBit(Math.max(1, Math.min(raw, 128))).","Fix the JSON/column config source so the literal value passed down is valid."],"exampleFix":"// before\nint bucketSize = config.getBucketSize(); // e.g. 100\nwriter = new FrontCodedIntArrayIndexedWriter(medium, ByteOrder.nativeOrder(), bucketSize);\n// after\nint raw = config.getBucketSize();\nint bucketSize = Integer.highestOneBit(Math.max(1, Math.min(raw, 128)));\nwriter = new FrontCodedIntArrayIndexedWriter(medium, ByteOrder.nativeOrder(), bucketSize);","handlingStrategy":"validation","validationCode":"static int normalizeBucketSize(int raw) {\n  if (raw >= 1 && raw <= 128 && Integer.bitCount(raw) == 1) return raw;\n  throw new IllegalArgumentException(\"bucketSize must be a power of two in [1,128], got \" + raw);\n}","typeGuard":"boolean isValidBucketSize(int n) { return n >= 1 && n <= 128 && Integer.bitCount(n) == 1; }","tryCatchPattern":null,"preventionTips":["Always derive bucketSize via Integer.highestOneBit / nextPowerOfTwo helpers","Validate user config at parse time, before writer construction","Keep allowed constants (1,2,4,...,128) in an enum or whitelist"],"tags":["java","segment-writer","validation"],"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"}