java-native-access/jna · error · IndexOutOfBoundsException

Bounds exceeds available space : size=<size>, offset=<off+sz

Error message

Bounds exceeds available space : size=<size>, offset=<off+sz>

What it means

Memory.boundsCheck() also verifies that offset+requested-size stays within this Memory block's allocated size. When off + sz > size, the access would write/read outside the malloc'ed space, so JNA throws IndexOutOfBoundsException with the block size and the offending end offset.

Source

Thrown at src/com/sun/jna/Memory.java:224

    }

    public long size() {
        return size;
    }

    /**
     * Check that indirection won't cause us to write outside the
     * malloc'ed space.
     *
     */
    protected void boundsCheck(long off, long sz) {
        if (off < 0) {
            throw new IndexOutOfBoundsException("Invalid offset: " + off);
        }
        if (off + sz > size) {
            String msg = "Bounds exceeds available space : size="
                + size + ", offset=" + (off + sz);
            throw new IndexOutOfBoundsException(msg);
        }
    }

    //////////////////////////////////////////////////////////////////////////
    // Raw read methods
    //////////////////////////////////////////////////////////////////////////

    /**
     * Indirect the native pointer to <code>malloc</code> space, a la
     * <code>Pointer.read</code>.  But this method performs a bounds
     * checks to ensure that the indirection does not cause memory outside the
     * <code>malloc</code>ed space to be accessed.
     *
     * @see Pointer#read(long,byte[],int,int)
     */
    @Override
    public void read(long bOff, byte[] buf, int index, int length) {
        boundsCheck(bOff, length * 1L);

View on GitHub (pinned to d036ad9781)

Solutions

  1. Increase the allocated size: new Memory(requiredSize) with size >= off + sz.
  2. Compute sizes from the actual data (STRUCTURE.SIZE, array lengths) rather than hardcoded constants.
  3. Clamp or validate length before access: assert off + sz <= memory.size().
  4. Re-share the full backing Memory with the correct offset/size instead of over-reading a slice.

Example fix

// before
Memory mem = new Memory(8);
mem.read(0, buf, 0, 16); // throws: 16 > 8
// after
Memory mem = new Memory(buf.length); // size matches the data
mem.read(0, buf, 0, buf.length);
Defensive patterns

Strategy: validation

Validate before calling

long end = offset + requestedBytes;
if (end > memory.size()) {
    throw new IllegalArgumentException("read of " + requestedBytes + " at " + offset + " exceeds size " + memory.size());
}
memory.read(offset, buffer, 0, requestedBytes);

Type guard

boolean fitsIn(Memory m, long off, long sz) {
    return off >= 0 && sz >= 0 && off + sz <= m.size();
}

Try / catch

try {
    memory.read(offset, buffer, 0, len);
} catch (IndexOutOfBoundsException e) {
    // grow or clamp
    memory = new Memory(offset + len);
    memory.read(offset, buffer, 0, len);
}

Prevention

When it happens

Trigger: Any Memory accessor whose offset plus access size exceeds the block: e.g. new Memory(8).readLong(4), read(0, buf, 0, 16) on a 8-byte block, setString near the end with a string longer than remaining space, or using a share() slice and indexing beyond the slice.

Common situations: Reading C arrays/structs with wrong element size or count; assuming a buffer is larger than it is after Memory.share; off-by-one in loops copying data; wrong struct size after a native API change.

Related errors


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/433f70cb23a86aff. Report an issue: GitHub.