netty/netty · error · IllegalArgumentException
directMemoryCacheAlignment: {} (expected: power of two)
Error message
directMemoryCacheAlignment: {} (expected: power of two) What it means
Thrown by the PooledByteBufAllocator constructor when directMemoryCacheAlignment is not a power of two. The test (alignment & -alignment) != alignment isolates the lowest set bit; equality holds only for powers of two. It is an IllegalArgumentException: the allocator aligns buffer addresses via bit-masking, which requires a single-bit alignment value.
Source
Thrown at buffer/src/main/java/io/netty/buffer/PooledByteBufAllocator.java:300
"Either Unsafe or ByteBuffer.alignSlice() must be available.");
}
// Ensure page size is a whole multiple of the alignment, or bump it to the next whole multiple.
pageSize = (int) PlatformDependent.align(pageSize, directMemoryCacheAlignment);
}
chunkSize = validateAndCalculateChunkSize(pageSize, maxOrder);
checkPositiveOrZero(nHeapArena, "nHeapArena");
checkPositiveOrZero(nDirectArena, "nDirectArena");
checkPositiveOrZero(directMemoryCacheAlignment, "directMemoryCacheAlignment");
if (directMemoryCacheAlignment > 0 && !isDirectMemoryCacheAlignmentSupported()) {
throw new IllegalArgumentException("directMemoryCacheAlignment is not supported");
}
if ((directMemoryCacheAlignment & -directMemoryCacheAlignment) != directMemoryCacheAlignment) {
throw new IllegalArgumentException("directMemoryCacheAlignment: "
+ directMemoryCacheAlignment + " (expected: power of two)");
}
int pageShifts = validateAndCalculatePageShifts(pageSize, directMemoryCacheAlignment);
if (nHeapArena > 0) {
heapArenas = newArenaArray(nHeapArena);
List<PoolArenaMetric> metrics = new ArrayList<PoolArenaMetric>(heapArenas.length);
final SizeClasses sizeClasses = new SizeClasses(pageSize, pageShifts, chunkSize, 0);
for (int i = 0; i < heapArenas.length; i ++) {
PoolArena.HeapArena arena = new PoolArena.HeapArena(this, sizeClasses);
heapArenas[i] = arena;
metrics.add(arena);
}
heapArenaMetrics = Collections.unmodifiableList(metrics);
} else {
heapArenas = null;
heapArenaMetrics = Collections.emptyList();View on GitHub (pinned to 70040aacae)
Solutions
- Use a power of two: 1, 2, 4, 8, 16, 32, 64, 128 (64 is typical for cache lines).
- Round up: alignment = Integer.highestOneBit(requested - 1) << 1; then guard against 0.
- If alignment is unnecessary, set it to 0.
Example fix
// before new PooledByteBufAllocator(true, nHeap, nDirect, pageSize, maxOrder, small, normal, true, 48); // after int alignment = Integer.highestOneBit(requestedLine - 1) << 1; // 48 -> 64 new PooledByteBufAllocator(true, nHeap, nDirect, pageSize, maxOrder, small, normal, true, alignment);
Defensive patterns
Strategy: validation
Validate before calling
static int pow2Alignment(int requested) {
if (requested <= 0) return 0;
int p = Integer.highestOneBit(requested - 1) << 1;
return p < 1 ? 1 : p;
} Type guard
null
Try / catch
null
Prevention
- Use powers of two for alignment (64 is typical for cache lines).
- Round up non-powers-of-two with highestOneBit before passing.
- Set alignment to 0 when alignment is not required.
When it happens
Trigger: Passing a directMemoryCacheAlignment such as 3, 6, 12, 24, 48 — non-powers of two that a developer picked from a CPU cache-line intuition without converting to the nearest power of two.
Common situations: Using the literal L1/L2 cache line size (e.g. 48 or 96 bytes on some CPUs) instead of rounding to 32/64/128; mirroring a C struct alignment value that is not a power of two.
Related errors
- Alignment cannot be greater than page size. Alignment: {}, p
- freeSweepAllocationThreshold: {} (expected: > 0)
- directMemoryCacheAlignment is not supported
- pageSize: {} (expected: {})
- pageSize: {} (expected: power of 2)
AI-assisted analysis of netty/netty@70040aacae (2026-08-14).
Data as JSON: /api/errors/fde44705db9185a1.
Report an issue: GitHub.