java-native-access/jna · error · IllegalArgumentException

Insufficient memory to align to the requested boundary

Error message

Insufficient memory to align to the requested boundary

What it means

Memory.align() adjusts this native memory block's start address up to the given byte boundary. When rounding the address up, the remaining usable space (newSize = peer + size - newPeer) can become zero or negative, meaning the aligned view would have no bytes left. JNA throws IllegalArgumentException in that case rather than returning an empty/shrunk Memory.

Source

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

     * power of two.
     * @throws IndexOutOfBoundsException if the requested alignment can
     * not be met.
     * @throws IllegalArgumentException if the requested alignment is not
     * a positive power of two.
     */
    public Memory align(int byteBoundary) {
        if (byteBoundary <= 0) {
            throw new IllegalArgumentException("Byte boundary must be positive: " + byteBoundary);
        }
        for (int i=0;i < 32;i++) {
            if (byteBoundary == (1<<i)) {
                long mask = ~((long)byteBoundary - 1);

                if ((peer & mask) != peer) {
                    long newPeer = (peer + byteBoundary - 1) & mask;
                    long newSize = peer + size - newPeer;
                    if (newSize <= 0) {
                        throw new IllegalArgumentException("Insufficient memory to align to the requested boundary");
                    }
                    return (Memory)share(newPeer - peer, newSize);
                }
                return this;
            }
        }
        throw new IllegalArgumentException("Byte boundary must be a power of two");
    }

    /** Free the native memory and set peer to zero */
    @Override
    public void close() {
        peer = 0;
        if (cleanable != null) {
            cleanable.clean();
        }
    }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Allocate a larger Memory block than needed so there is slack for boundary rounding (e.g. size + boundary).
  2. Use a smaller byteBoundary that the block can accommodate.
  3. Align once at allocation time (new Memory(size).align(boundary) on a suitably sized buffer) instead of aligning small shared slices.
  4. Check math before calling: if ((peer + size) rounded down to boundary) <= peer, the align cannot succeed.

Example fix

// before
Memory m = new Memory(4);
Memory aligned = m.align(16); // throws: nothing left after rounding up
// after
Memory m = new Memory(4 + 16);
Memory aligned = m.align(16); // slack guarantees space survives alignment
Defensive patterns

Strategy: validation

Validate before calling

long mask = ~(boundary - 1);
long newPeer = (peer + boundary - 1) & mask;
long newSize = peer + size - newPeer;
if (newSize <= 0) {
    throw new IllegalArgumentException("block too small for boundary " + boundary);
}
Memory aligned = memory.align(boundary);

Type guard

boolean canAlign(Memory m, long boundary) {
    return Long.bitCount(boundary) == 1 && m.size() >= boundary;
}

Try / catch

try {
    aligned = memory.align(boundary);
} catch (IllegalArgumentException e) {
    aligned = new Memory(size + boundary).align(boundary); // reallocate with slack
}

Prevention

When it happens

Trigger: Calling memory.align(byteBoundary) (directly or via memory.aligned()) where the current peer address is not already on the boundary and the number of bytes remaining after rounding up the address is <= 0 — i.e. the block is too small (or the offset too deep) to survive alignment.

Common situations: Aligning a small Memory block or a shared/sliced region (e.g. obtained from Memory.share) to a large boundary such as 8 or 16 bytes; writing tests like testNegativeAlignment/testInvalidAlignment that align blocks with little or no slack.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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