prestodb/presto · error · IllegalArgumentException
isNull length is less than positionCount
Error message
isNull length is less than positionCount
What it means
ByteArrayBlock's constructor validates that, when a null-value map (valueIsNull) is supplied, it has at least positionCount entries after arrayOffset. If valueIsNull.length - arrayOffset < positionCount, the block could not answer isNull(position) for every valid position, so the library throws IllegalArgumentException. Passing null for valueIsNull is allowed and means no value is null.
Solutions
- Ensure valueIsNull.length - arrayOffset >= positionCount, or allocate valueIsNull = new boolean[positionCount]
- Pass null for valueIsNull if no values are null (avoids the check and reduces retained size)
- Resize the null mask before construction, e.g. Arrays.copyOf(isNull, positionCount)
- Audit where the null mask is produced so its length always matches the values batch
Example fix
// before new ByteArrayBlock(100, Optional.of(new boolean[64]), values, null); // throws // after new ByteArrayBlock(100, Optional.of(new boolean[100]), values, null);
Defensive patterns
Strategy: validation
Validate before calling
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
valueIsNull = Arrays.copyOfRange(valueIsNull, 0, positionCount); // pad to required length
}
Block block = new ByteArrayBlock(positionCount, Optional.ofNullable(valueIsNull), values);
Type guard
boolean nullMaskCovers(boolean[] valueIsNull, int positionCount, int arrayOffset) {
return valueIsNull == null || valueIsNull.length - arrayOffset >= positionCount;
}
Try / catch
try {
Block block = new ByteArrayBlock(positionCount, Optional.ofNullable(valueIsNull), values);
} catch (IllegalArgumentException e) {
throw new IllegalStateException("null mask length must cover positionCount: " + e.getMessage(), e);
}
Prevention
- Allocate null masks with exactly new boolean[positionCount]
- Pass null (or Optional.empty()) when no value is null instead of reusing a small mask
- Resize masks when batching multiple chunks into one block
When it happens
Trigger: Calling new ByteArrayBlock(positionCount, valueIsNull, values, ...) with a valueIsNull array shorter than positionCount (minus arrayOffset); reusing a null map built for a smaller batch; supplying a valueIsNull array after slicing with an arrayOffset but forgetting to grow the array.
Common situations: Vectorized writers writing per-chunk null masks sized to the chunk not the block; serializers copying a null bitmap of the wrong bit-length; code paths that build valueIsNull only for nullable columns and pass an undersized stale array.
Related errors
- isNull length is less than positionCount
- values length is less than positionCount
- A null map must have zero entries
- Access control ' ' is already registered
- arrayOffset is negative
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/46979eeec2024cd0.
Report an issue: GitHub.
Appendix: source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/ByteArrayBlock.java:80
ByteArrayBlock(int arrayOffset, int positionCount, boolean[] valueIsNull, byte[] values)
{
if (arrayOffset < 0) {
throw new IllegalArgumentException("arrayOffset is negative");
}
this.arrayOffset = arrayOffset;
if (positionCount < 0) {
throw new IllegalArgumentException("positionCount is negative");
}
this.positionCount = positionCount;
if (values.length - arrayOffset < positionCount) {
throw new IllegalArgumentException("values length is less than positionCount");
}
this.values = values;
if (valueIsNull != null && valueIsNull.length - arrayOffset < positionCount) {
throw new IllegalArgumentException("isNull length is less than positionCount");
}
this.valueIsNull = valueIsNull;
retainedSizeInBytes = (INSTANCE_SIZE + sizeOf(valueIsNull) + sizeOf(values));
}
@Override
public long getSizeInBytes()
{
return SIZE_IN_BYTES_PER_POSITION * (long) positionCount;
}
@Override
public long getRegionSizeInBytes(int position, int length)
{
return SIZE_IN_BYTES_PER_POSITION * (long) length;
}
View on GitHub (pinned to 55bb57d202)