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

  1. Clamp positionOffset/length to the block's getPositionCount() before slicing
  2. Use getRegionLength()/getSliceLength to derive length instead of hardcoding
  3. 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

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


AI-assisted analysis of prestodb/presto@55bb57d202 (2026-09-04). Data as JSON: /api/errors/6655b242512573a4. Report an issue: GitHub.