elastic/elasticsearch · error · IllegalArgumentException
blockSize must be a power of 2 in [{}, {}], got: {}
Error message
blockSize must be a power of 2 in [{}, {}], got: {} What it means
Thrown by the ColumNARDocValuesFormat constructor when blockSize fails any of three checks: below MIN_BLOCK_SIZE (128), above MAX_BLOCK_SIZE (8192), or not a power of two (the classic `n & (n-1) != 0` test). Block size bounds O(blockSize) per-field encoder allocations, and power-of-two is required by the bit-packing terminal. The SPI/no-arg constructor uses DEFAULT_BLOCK_SIZE (128); only explicit construction can hit this.
Source
Thrown at libs/columnar/src/main/java/org/elasticsearch/columnar/ColumNARDocValuesFormat.java:64
static final String DATA_CODEC = "ColumNARNumericData";
static final String DATA_EXTENSION = "cnvd";
static final String META_CODEC = "ColumNARNumericMeta";
static final String META_EXTENSION = "cnvm";
private final NumericPipelineSelector pipelineSelector;
private final int blockSize;
/**
* Constructs the format with a custom per-field pipeline selector and an explicit block size.
* The block size controls how many values are grouped into each encoded block; it must be a
* power of 2 between {@value #MIN_BLOCK_SIZE} and {@value #MAX_BLOCK_SIZE} inclusive.
*
* @throws IllegalArgumentException if {@code blockSize} is not a power of 2 in [{@value #MIN_BLOCK_SIZE}, {@value #MAX_BLOCK_SIZE}]
*/
public ColumNARDocValuesFormat(NumericPipelineSelector pipelineSelector, int blockSize) {
super(ColumnarFormat.NAME);
if (blockSize < MIN_BLOCK_SIZE || blockSize > MAX_BLOCK_SIZE || (blockSize & (blockSize - 1)) != 0) {
throw new IllegalArgumentException(
"blockSize must be a power of 2 in [" + MIN_BLOCK_SIZE + ", " + MAX_BLOCK_SIZE + "], got: " + blockSize
);
}
this.pipelineSelector = pipelineSelector;
this.blockSize = blockSize;
}
/** Constructs the format with a custom per-field pipeline selector and the default block size. */
public ColumNARDocValuesFormat(NumericPipelineSelector pipelineSelector) {
this(pipelineSelector, DEFAULT_BLOCK_SIZE);
}
/** SPI constructor. Uses the default pipeline for every field. */
public ColumNARDocValuesFormat() {
this((fieldName, type) -> NumericPipeline::defaultPipeline);
}
@OverrideView on GitHub (pinned to db6a809a66)
Solutions
- Use one of the documented powers of two in [128, 8192]: 128, 256, 512, 1024, 2048, 4096, 8192.
- Prefer the no-arg/SPI constructor or the single-arg constructor, which use DEFAULT_BLOCK_SIZE (128).
- If accepting user input, validate: `Integer.bitCount(blockSize) == 1 && blockSize >= 128 && blockSize <= 8192` before constructing.
- Round the requested size up to the next power of two and clamp into [128, 8192].
Example fix
// before new ColumNARDocValuesFormat(selector, 1000); // throws // after new ColumNARDocValuesFormat(selector, 1024); // valid power of two in range
Defensive patterns
Strategy: validation
Validate before calling
void requireValidBlockSize(int blockSize) {
if (Integer.bitCount(blockSize) != 1
|| blockSize < ColumNARDocValuesFormat.MIN_BLOCK_SIZE
|| blockSize > ColumNARDocValuesFormat.MAX_BLOCK_SIZE) {
throw new IllegalArgumentException("blockSize must be a power of 2 in [128, 8192], got: " + blockSize);
}
} Type guard
static boolean isValidBlockSize(int blockSize) {
return Integer.bitCount(blockSize) == 1
&& blockSize >= ColumNARDocValuesFormat.MIN_BLOCK_SIZE
&& blockSize <= ColumNARDocValuesFormat.MAX_BLOCK_SIZE;
} Try / catch
try {
return new ColumNARDocValuesFormat(selector, blockSize);
} catch (IllegalArgumentException e) {
// fall back to the documented default rather than propagating a misconfiguration
return new ColumNARDocValuesFormat(selector); // uses DEFAULT_BLOCK_SIZE = 128 Prevention
- Prefer the no-arg/SPI or single-arg constructor unless you have a measured reason to change block size.
- When exposing block size as a config, validate power-of-two and range before construction.
- Round requested sizes to the nearest valid power of two within [128, 8192].
- Keep the validation helper close to the call site so it evolves with the constants.
When it happens
Trigger: Constructing `new ColumNARDocValuesFormat(selector, blockSize)` with values like 100 (below min), 9000 (above max), 1000 (not power of two), 256 (valid), or 8192 (valid). Also if a codec is instantiated reflectively/SPI from a config string parsed to an invalid int.
Common situations: A test tuning block size for benchmarking and guessing a value. Config plumbing that forwards a user int without validating the power-of-two constraint. Migrating a Lucene codecs param (where 1–512 ranges are common) without re-scaling to ColumNAR's 128–8192 range.
Related errors
- ColumNAR field type [{}] is not implemented yet
- {} must be non-negative, got [{}]
- Dataset dimensions must be positive: rows={}, features={}
- Resource count must be between 1 and 4
- input cannot be null
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/6de84dfff511ba07.
Report an issue: GitHub.