prestodb/presto · error · java.lang.IndexOutOfBoundsException

Invalid position %s and length %s in page with %s positions

Error message

Invalid position %s and length %s in page with %s positions

What it means

Page.getRegion(positionOffset, length) extracts a sub-page; it throws IndexOutOfBoundsException when positionOffset is negative, length is negative, or positionOffset + length exceeds the page's positionCount. This guards against reading outside the page's valid position range.

Source

Thrown at presto-common/src/main/java/com/facebook/presto/common/Page.java:185

    /**
     * Gets the values at the specified position as a single element page.  The method creates independent
     * copy of the data.
     */
    public Page getSingleValuePage(int position)
    {
        Block[] singleValueBlocks = new Block[this.blocks.length];
        for (int i = 0; i < this.blocks.length; i++) {
            singleValueBlocks[i] = this.blocks[i].getSingleValueBlock(position);
        }
        return wrapBlocksWithoutCopy(1, singleValueBlocks);
    }

    // getRegion() is used to get a sub-page or region of a page based on the given positionOffset and length
    public Page getRegion(int positionOffset, int length)
    {
        if (positionOffset < 0 || length < 0 || positionOffset + length > positionCount) {
            throw new IndexOutOfBoundsException(format("Invalid position %s and length %s in page with %s positions", positionOffset, length, positionCount));
        }

        // Avoid creating new objects when region is same as original page
        if (positionOffset == 0 && length == positionCount) {
            return this;
        }

        // Create a new page view with the specified region
        int channelCount = getChannelCount();
        Block[] slicedBlocks = new Block[channelCount];
        for (int i = 0; i < channelCount; i++) {
            slicedBlocks[i] = blocks[i].getRegion(positionOffset, length);
        }
        return wrapBlocksWithoutCopy(length, slicedBlocks);
    }

    public Page appendColumn(Block block)
    {

View on GitHub (pinned to 55bb57d202)

Solutions

  1. Clamp length: use Math.min(offset + length, page.getPositionCount()) - offset before calling getRegion.
  2. Check the page's actual positionCount via getPositionCount() and compute the region bounds from it.
  3. Fix off-by-one arithmetic in the calling operator or pagination logic.
  4. Add an assertion/unit test that validates offsets against the page size for your custom operator.

Example fix

// before
Page region = page.getRegion(pageOffset, batchSize);
// after
int len = Math.min(batchSize, page.getPositionCount() - pageOffset);
Page region = len > 0 ? page.getRegion(pageOffset, len) : null;
Defensive patterns

Strategy: validation

Validate before calling

boolean isValidRegion(Page page, int offset, int length) {
    return page != null && offset >= 0 && length >= 0 && offset + length <= page.getPositionCount();
}

Type guard

Page safeGetRegion(Page page, int offset, int length) {
    if (page == null || offset < 0 || length < 0 || offset + length > page.getPositionCount()) {
        return null;
    }
    return page.getRegion(offset, length);
}

Try / catch

try {
    return page.getRegion(offset, length);
} catch (IndexOutOfBoundsException e) {
    log.warn("Region request [%d,%d] outside page size %d", offset, length, page.getPositionCount());
    return page.getPositionCount() > 0 ? page.getRegion(0, page.getPositionCount()) : Page.EMPTY;
}

Prevention

When it happens

Trigger: Calling page.getRegion(offset, len) with offset < 0, len < 0, or offset+len > page.getPositionCount(), e.g. requesting 1000 rows from a page that only has 500.

Common situations: Off-by-one errors in custom page processors/operators, pagination code assuming fixed page sizes larger than the actual final page, downstream operators not checking positionCount before slicing, or stale row counts after filtering.

Related errors


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