java-native-access/jna · error · IllegalArgumentException
Byte boundary must be a power of two
Error message
Byte boundary must be a power of two
What it means
Memory.align() only supports byte boundaries that are powers of two (1, 2, 4, 8, 16...), because it computes the aligned address with a bitmask (~boundary-1). Any other value cannot produce a valid mask, so JNA falls through the loop and throws IllegalArgumentException.
Source
Thrown at src/com/sun/jna/Memory.java:181
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();
}
}
@Deprecated
protected void dispose() {
close();
}
/** Zero the full extent of this memory region. */
public void clear() {View on GitHub (pinned to d036ad9781)
Solutions
- Pass a power-of-two boundary: use Integer.highestOneBit(n) or the next power of two ≥ n.
- Use a standard alignment constant (1, 2, 4, 8, 16).
- Guard the call: if (Integer.bitCount(boundary) != 1) pick a valid boundary before aligning.
Example fix
// before Memory aligned = mem.align(6); // IllegalArgumentException // after int boundary = Integer.highestOneBit(6) * 2; // 8, next power of two Memory aligned = mem.align(boundary);
Defensive patterns
Strategy: validation
Validate before calling
if (boundary <= 0 || Long.bitCount(boundary) != 1) {
throw new IllegalArgumentException("boundary must be a positive power of two: " + boundary);
}
Memory aligned = memory.align(boundary); Type guard
boolean isPowerOfTwo(long n) {
return n > 0 && (n & (n - 1)) == 0;
} Try / catch
try {
aligned = memory.align(boundary);
} catch (IllegalArgumentException e) {
long next = Long.highestOneBit(boundary) * 2; // round up to next power of two
aligned = memory.align(next);
} Prevention
- Only pass literal powers of two (1, 2, 4, 8, 16, 32).
- Derive boundaries with Integer/Long.highestOneBit instead of hand-computed values.
- Assert isPowerOfTwo(boundary) in debug builds before calling align.
When it happens
Trigger: Calling memory.align(n) or aligned(n) where n is not a power of two, e.g. align(3), align(6), align(0), or a negative value — the while loop (boundary >= 2, halving) never matches and control reaches the throw.
Common situations: Passing a struct size or alignment guess like 3 or 6 instead of the next power of two; typos such as align(10); unit tests testInvalidAlignment exercising invalid boundaries.
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
- Insufficient memory to align to the requested boundary
- Byte boundary must be positive: <byteBoundary>
- Invalid offset: <off>
- Bounds exceeds available space : size=<size>, offset=<off+sz
- Reading \"" + type + "\" from memory is not supported
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/e2580ccf588d9fd2.
Report an issue: GitHub.