prestodb/presto · error · IndexOutOfBoundsException
Invalid position %s and length %s in block with %s positions
Error message
Invalid position %s and length %s in block with %s positions
What it means
BlockUtil.checkValidRegion validates a region view (positionOffset, length) against a block's positionCount, throwing IndexOutOfBoundsException when positionOffset is negative, length is negative, or positionOffset+length exceeds positionCount. It guards Block.getRegion-style slicing so no region references positions outside the block.
Source
Thrown at presto-common/src/main/java/com/facebook/presto/common/block/BlockUtil.java:61
{
requireNonNull(array, "array is null");
if (offset < 0 || length < 0 || offset + length > array.length) {
throw new IndexOutOfBoundsException(format("Invalid offset %s and length %s in array with %s elements", offset, length, array.length));
}
}
static void checkArrayRange(boolean[] array, int offset, int length)
{
requireNonNull(array, "array is null");
if (offset < 0 || length < 0 || offset + length > array.length) {
throw new IndexOutOfBoundsException(format("Invalid offset %s and length %s in array with %s elements", offset, length, array.length));
}
}
static void checkValidRegion(int positionCount, int positionOffset, int length)
{
if (positionOffset < 0 || length < 0 || positionOffset + length > positionCount) {
throw new IndexOutOfBoundsException(format("Invalid position %s and length %s in block with %s positions", positionOffset, length, positionCount));
}
}
static void checkValidPositions(boolean[] positions, int positionCount)
{
if (positions.length != positionCount) {
throw new IllegalArgumentException(format("Invalid positions array size %d, actual position count is %d", positions.length, positionCount));
}
}
static void checkValidPosition(int position, int positionCount)
{
if (position < 0 || position >= positionCount) {
throw new IllegalArgumentException(format("Invalid position %s in block with %s positions", position, positionCount));
}
}
static void checkValidSliceRange(int sourceIndex, int length)View on GitHub (pinned to 55bb57d202)
Solutions
- Clamp positionOffset/length to the block's getPositionCount() before slicing
- Use getRegionLength()/getSliceLength to derive length instead of hardcoding
- Catch IndexOutOfBoundsException and surface which block and offsets were invalid
Example fix
// before Block region = block.getRegion(offset, remaining); // after int len = Math.min(remaining, block.getPositionCount() - offset); Block region = block.getRegion(offset, len);
Defensive patterns
Strategy: validation
Validate before calling
if (positionOffset < 0 || length < 0 || positionOffset > positionCount - length) {
throw new IllegalArgumentException("bad region: offset=" + positionOffset + " length=" + length + " positions=" + positionCount);
} Type guard
boolean isValidRegion(int positionCount, int positionOffset, int length) {
return positionOffset >= 0 && length >= 0 && positionOffset <= positionCount - length;
} Try / catch
try {
region = block.getRegion(positionOffset, length);
} catch (IndexOutOfBoundsException e) {
throw new PrestoException(GENERIC_INTERNAL_ERROR, "invalid region " + positionOffset + "+" + length + " of " + block.getPositionCount(), e);
} Prevention
- Clamp requested length against block.getPositionCount() before slicing
- Derive region bounds from the block API (getRegionLength) rather than cached sizes
- Add assertions on offset math in custom Block implementations
When it happens
Trigger: Calling Block.getRegion (or a custom block that calls checkValidRegion) with a positionOffset or length computed from bad row math — e.g. requesting more positions than the block holds, or offset+length overflowing int.
Common situations: Paging/streaming code that assumes blocks always carry a fixed position count; cursor arithmetic bugs after partial reads; custom Block subclasses passing regionLength defaults larger than the block.
Related errors
- Invalid channel %d in page with %s channels
- Invalid positions array size %d, actual position count is %d
- Invalid position %s in block with %s positions
- Cannot allocate slice larger than %d bytes
- position is not valid:
AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04).
Data as JSON: /api/errors/6655b242512573a4.
Report an issue: GitHub.