apache/druid · error · IllegalArgumentException

bucketSize must be a power of two (from 1 up to 128) but…

Error message

bucketSize must be a power of two (from 1 up to 128) but was[%,d]

What it means

FrontCodedIndexedWriter's constructor validates that bucketSize is a power of two between 1 and 128 inclusive. Power-of-two bucket sizes are required for the bit-shift based indexing, and the 1..128 cap bounds memory (bucketBuffer and scratch sizing). Invalid values throw IAE before any writing happens.

Solutions

  1. Set bucketSize to a power of two between 1 and 128 (the default is 4)
  2. Validate user config before passing it to the writer: (bucketSize & (bucketSize - 1)) == 0 && bucketSize >= 1 && bucketSize <= 128
  3. Use FrontCodedIndexed.write() helpers or config parsing that clamps/validates the bucket size automatically
  4. If coming from SQL/ingestion spec, correct the 'compressionFormat': 'frontCoded' with a legal bucketSize parameter

Example fix

// before
int bucketSize = 5;
new FrontCodedIndexedWriter<>(medium, ordering, byteOrder, bucketSize, version); // IAE
// after
int bucketSize = 8; // power of two, 1..128
new FrontCodedIndexedWriter<>(medium, ordering, byteOrder, bucketSize, version);
Defensive patterns

Strategy: validation

Validate before calling

boolean validBucketSize(int n) {
  return n >= 1 && n <= 128 && Integer.bitCount(n) == 1;
}
// call before constructing: if (!validBucketSize(bucketSize)) fail fast

Try / catch

try {
  writer = new FrontCodedIndexedWriter<>(medium, ordering, byteOrder, bucketSize, version);
} catch (IllegalArgumentException e) {
  // fall back to DEFAULT_BUCKET_SIZE (4) or reject the config
}

Prevention

When it happens

Trigger: Constructing FrontCodedIndexedWriter with bucketSize values like 0, 3, 5, 6, or 256 — i.e. any value failing Integer.bitCount(bucketSize) == 1 || bucketSize < 1 || bucketSize > 128. This typically comes from a user-supplied frontCoded bucketSize config (e.g. SQL dictionary compression config) that was not validated.

Common situations: Setting the front-coded dictionary compression bucket size in ingestion/SQL configs to a non-power-of-two like 5 or 10; copy-paste of an example bucketSize; assuming any positive size is allowed.

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


AI-assisted analysis of apache/druid@9b90983fd2 (2026-09-07). Data as JSON: /api/errors/f4266015f1d57161. Report an issue: GitHub.

Appendix: source

Thrown at processing/src/main/java/org/apache/druid/segment/data/FrontCodedIndexedWriter.java:86

  private WriteOutBytes headerOut = null;
  @Nullable
  private WriteOutBytes valuesOut = null;
  private int numWritten = 0;
  private ByteBuffer scratch;
  private int logScratchSize = 10;
  private boolean isClosed = false;
  private boolean hasNulls = false;


  public FrontCodedIndexedWriter(
      SegmentWriteOutMedium segmentWriteOutMedium,
      ByteOrder byteOrder,
      int bucketSize,
      byte version
  )
  {
    if (Integer.bitCount(bucketSize) != 1 || bucketSize < 1 || bucketSize > 128) {
      throw new IAE("bucketSize must be a power of two (from 1 up to 128) but was[%,d]", bucketSize);
    }
    this.segmentWriteOutMedium = segmentWriteOutMedium;
    this.scratch = ByteBuffer.allocate(1 << logScratchSize).order(byteOrder);
    this.bucketSize = bucketSize;
    this.byteOrder = byteOrder;
    this.bucketBuffer = new byte[bucketSize][];
    this.getOffsetBuffer = ByteBuffer.allocate(Integer.BYTES).order(byteOrder);
    this.div = Integer.numberOfTrailingZeros(bucketSize);
    this.version = FrontCodedIndexed.validateVersion(version);
  }

  @Override
  public void open() throws IOException
  {
    headerOut = segmentWriteOutMedium.makeWriteOutBytes();
    valuesOut = segmentWriteOutMedium.makeWriteOutBytes();
  }

View on GitHub (pinned to 9b90983fd2)