pinpoint-apm/pinpoint · error · ArrayIndexOutOfBoundsException

End index must not be greater than the array length

Error message

End index must not be greater than the array length

What it means

ArrayViewList is a fixed-size view over an existing array; its constructor validates that endIndex does not exceed array.length. This ArrayIndexOutOfBoundsException is thrown eagerly when constructing a view whose end index would point past the backing array, preventing later reads from escaping array bounds.

Source

Thrown at agent-module/profiler/src/main/java/com/navercorp/pinpoint/profiler/util/queue/ArrayViewList.java:34

 */

package com.navercorp.pinpoint.profiler.util.queue;

import java.util.AbstractList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.RandomAccess;

public class ArrayViewList<E> extends AbstractList<E> implements RandomAccess, java.io.Serializable
{
    private final E[] array;
    private final int endIndex;

    public ArrayViewList(E[] array, int endIndex) {
        if (endIndex > array.length) {
            throw new ArrayIndexOutOfBoundsException("End index must not be greater than the array length");
        }
        this.array = Objects.requireNonNull(array);
        this.endIndex = endIndex;
    }

    @Override
    public boolean add(E e) {
        throw new UnsupportedOperationException();
    }

    @Override
    public int size() {
        return endIndex;
    }

    @Override
    public Object[] toArray() {
        return Arrays.copyOf(array, endIndex);

View on GitHub (pinned to 744c3d3075)

Solutions

  1. Fix the caller to pass endIndex <= array.length (typically endIndex == array.length or start + size)
  2. Verify the array reference passed is the same one whose length the endIndex was computed from
  3. Add an assertion/log at the call site to capture the array length and endIndex values

Example fix

// before
return new ArrayViewList<>(buffer, head + size); // head + size may exceed length
// after
int endIndex = Math.min(head + size, buffer.length);
return new ArrayViewList<>(buffer, endIndex);
Defensive patterns

Strategy: validation

Validate before calling

if (endIndex < 0 || endIndex > array.length) throw new IllegalArgumentException("endIndex=" + endIndex + " length=" + array.length);
ArrayViewList<E> view = new ArrayViewList<>(array, endIndex);

Try / catch

try { view = new ArrayViewList<>(array, endIndex); } catch (ArrayIndexOutOfBoundsException e) { log.warn("bad endIndex={}, len={}", endIndex, array.length); view = Collections.emptyList(); }

Prevention

When it happens

Trigger: Calling new ArrayViewList<>(array, endIndex) where endIndex > array.length, e.g. after computing an end index from a bad size, an off-by-one, or a stale length value.

Common situations: Wrapping a circular/flush queue buffer where the stored size was recorded before the array shrank or was reused; off-by-one arithmetic like (start + count) computed on a different array instance.

Related errors


AI-assisted analysis of pinpoint-apm/pinpoint@744c3d3075 (2026-09-07). Data as JSON: /api/errors/b2f847c22cd13682. Report an issue: GitHub.