java-native-access/jna · error · IllegalArgumentException

Byte boundary must be positive: <byteBoundary>

Error message

Byte boundary must be positive: <byteBoundary>

What it means

Memory.align throws this IllegalArgumentException when the requested byteBoundary is not positive. The doc requires a positive power of two; non-positive values are rejected immediately, and non-powers-of-two fall through to the UnsupportedOperationException below the shown region.

Source

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

     * the allocated bounds.
     */
    @Override
    public Pointer share(long offset, long sz) {
        boundsCheck(offset, sz);
        return new SharedMemory(offset, sz);
    }

    /** Provide a view onto this structure with the given alignment.
     * @param byteBoundary Align memory to this number of bytes; should be a
     * 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");
    }

View on GitHub (pinned to d036ad9781)

Solutions

  1. Pass a positive power of two: 1, 2, 4, 8, 16, ...
  2. Compute alignment from the actual type: use Native.getNativeSize or Structure field alignment instead of hardcoded 0.
  3. Guard: if (boundary <= 0 || (boundary & (boundary-1)) != 0) fix before calling align().

Example fix

// before
int boundary = config.get("align", 0);
mem.align(boundary);
// after
int boundary = Math.max(1, config.get("align", 8));
mem.align(Integer.highestOneBit(boundary));
Defensive patterns

Strategy: validation

Validate before calling

static boolean isPowerOfTwo(int n) { return n > 0 && (n & (n - 1)) == 0; }
static Memory safeAlign(Memory m, int boundary) {
  if (!isPowerOfTwo(boundary)) throw new IllegalArgumentException("Alignment must be a positive power of two: " + boundary);
  return m.align(boundary);
}

Try / catch

try {
  Memory aligned = mem.align(boundary);
} catch (IllegalArgumentException e) {
  if (e.getMessage().startsWith("Byte boundary must be positive")) {
    throw new IllegalStateException("boundary=" + boundary + "; use a positive power of two", e);
  }
  throw e;
}

Prevention

When it happens

Trigger: mem.align(0) or mem.align(-4); boundary computed from an expression that yielded 0; passing a value like 6 (rejected by the power-of-two loop, not this message).

Common situations: Aligning buffers to struct member alignment where the alignment constant was uninitialized; computing alignment from sizeof results on empty structs; confusing byte boundary with byte offset.

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/643bda251ce73529. Report an issue: GitHub.