apache/flink · error · IllegalStateException
Memory segment does not represent off heap memory
Error message
Memory segment does not represent off heap memory
What it means
MemorySegment.getAddress() returns the absolute native memory address, which is only meaningful for off-heap segments; it throws IllegalStateException('Memory segment does not represent off heap memory') when heapMemory != null. For heap segments the 'address' field is an offset into the heap array (unsafe machinery), not a real pointer.
Source
Thrown at flink-core/src/main/java/org/apache/flink/core/memory/MemorySegment.java:306
public ByteBuffer getOffHeapBuffer() {
if (offHeapBuffer != null) {
return offHeapBuffer;
} else {
throw new IllegalStateException("Memory segment does not represent off-heap buffer");
}
}
/**
* Returns the memory address of off-heap memory segments.
*
* @return absolute memory address outside the heap
* @throws IllegalStateException if the memory segment does not represent off-heap memory
*/
public long getAddress() {
if (heapMemory == null) {
return address;
} else {
throw new IllegalStateException("Memory segment does not represent off heap memory");
}
}
/**
* Wraps the chunk of the underlying memory located between <tt>offset</tt> and <tt>offset +
* length</tt> in a NIO ByteBuffer. The ByteBuffer has the full segment as capacity and the
* offset and length parameters set the buffers position and limit.
*
* @param offset The offset in the memory segment.
* @param length The number of bytes to be wrapped as a buffer.
* @return A <tt>ByteBuffer</tt> backed by the specified portion of the memory segment.
* @throws IndexOutOfBoundsException Thrown, if offset is negative or larger than the memory
* segment size, or if the offset plus the length is larger than the segment size.
*/
public ByteBuffer wrap(int offset, int length) {
if (!allowWrap) {
throw new UnsupportedOperationException(
"Wrap is not supported by this segment. This usually indicates that the underlying memory is unsafe, thus transferring of ownership is not allowed.");View on GitHub (pinned to 2f3c205e92)
Solutions
- Restrict getAddress() usage to segments where segment.isOffHeap() is true; for heap segments use getArray() plus sun.misc.Unsafe BYTE_ARRAY_BASE_OFFSET instead.
- Prefer the segment's own copy/compare/swap methods (copyTo, copyFromUnsafe, compare, swapBytes) which handle both backings, removing the need for raw addresses.
- If a long pointer is genuinely required, ensure the segment is allocated off-heap via MemorySegmentFactory.allocateOffHeapMemory.
Example fix
// before
long ptr = segment.getAddress() + offset; // IllegalStateException on heap segment
// after
long ptr = segment.isOffHeap()
? segment.getAddress() + offset
: Unsafe.ARRAY_BYTE_BASE_OFFSET + offset; // combined with segment.getArray() as unsafe base Defensive patterns
Strategy: validation
Validate before calling
if (segment.isOffHeap()) {
long ptr = segment.getAddress() + offset;
} else {
byte[] heap = segment.getArray(); // use with ARRAY_BYTE_BASE_OFFSET + offset
} Prevention
- Treat getAddress() as an off-heap-only API.
- Prefer MemorySegment's built-in copy/compare methods over raw pointer arithmetic — they handle both backings safely.
When it happens
Trigger: Calling getAddress() on a heap-backed segment (MemorySegmentFactory.wrap(byte[]), allocateUnpooledSegment) — usually to pass a raw pointer to unsafe code or native IO.
Common situations: Unsafe copy helpers that compute long pointers from segment.getAddress() + offset written for off-heap buffers but also invoked on heap segments; component reused between on-heap tests and off-heap production configurations.
Related errors
- Memory segment does not represent heap memory
- Memory segment does not represent off-heap buffer
- offset=%d, numBytes=%d, address=%d
- The given buffer is neither an array-backed heap ByteBuffer,
- Could not write {numBytes} bytes. Buffer overflow.
AI-assisted analysis of apache/flink@2f3c205e92 (2026-08-14).
Data as JSON: /api/errors/cdcb7457ef182570.
Report an issue: GitHub.