{"record":{"id":"cc7ea082e4c80935","repo":"netty/netty","slug":"direct-buffer","errorCode":null,"errorMessage":"direct buffer","messagePattern":"direct buffer","errorType":"exception","errorClass":"java.lang.UnsupportedOperationException","httpStatus":null,"severity":"error","filePath":"buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java","lineNumber":302,"sourceCode":"        tmpBuf.put(tmp, 0, readBytes);\n        return readBytes;\n    }\n\n    @Override\n    public ByteBuf copy(int index, int length) {\n        checkIndex(index, length);\n        ByteBuf copy = alloc().directBuffer(length, maxCapacity());\n        return copy.writeBytes(this, index, length);\n    }\n\n    @Override\n    public boolean hasArray() {\n        return false;\n    }\n\n    @Override\n    public byte[] array() {\n        throw new UnsupportedOperationException(\"direct buffer\");\n    }\n\n    @Override\n    public int arrayOffset() {\n        throw new UnsupportedOperationException(\"direct buffer\");\n    }\n\n    @Override\n    public boolean hasMemoryAddress() {\n        PoolChunk<ByteBuffer> chunk = this.chunk;\n        return chunk != null && chunk.cleanable.hasMemoryAddress();\n    }\n\n    @Override\n    public long memoryAddress() {\n        ensureAccessible();\n        if (!hasMemoryAddress()) {\n            throw new UnsupportedOperationException();","sourceCodeStart":284,"sourceCodeEnd":320,"githubUrl":"https://github.com/netty/netty/blob/70040aacae241e9ba371e758f5b86e470bd77ad1/buffer/src/main/java/io/netty/buffer/PooledDirectByteBuf.java#L284-L320","documentation":"Thrown by PooledDirectByteBuf.array() because a pooled direct (off-heap) ByteBuf does not back its data with an on-heap byte[]. Netty's contract requires hasArray() to be checked first; array() is only valid when hasArray() returns true. Calling array() on a direct buffer is a programming error, not a transient failure.","triggerScenarios":"Calling buf.array() on a buffer obtained from PooledByteBufAllocator.DEFAULT.directBuffer(...) or any allocator that returns PooledDirectByteBuf. Also hit when passing a pooled direct buffer to code that unconditionally invokes array() (e.g. some JDK helpers or legacy serializers).","commonSituations":"Switching an allocator from heap to direct in configuration, or migrating from Unpooled.buffer() (heap) to a pooled direct allocator. Third-party libraries (e.g. older message serializers, Kryo) that assume heap-backed buffers.","solutions":["Guard with if (buf.hasArray()) before calling buf.array().","Use buf.nioBuffer() / buf.nioBuffers() to obtain a ByteBuffer view instead of array().","Copy to a heap buffer first: ByteBuf heap = buf.copy(); if hasArray() is required downstream.","Configure the allocator/channel to use heap buffers if array() access is mandatory."],"exampleFix":"// before\nbyte[] data = buf.array();\n\n// after\nbyte[] data;\nif (buf.hasArray()) {\n    data = buf.array();\n} else {\n    data = new byte[buf.readableBytes()];\n    buf.getBytes(buf.readerIndex(), data);\n}","handlingStrategy":"type-guard","validationCode":"// Validate before calling array()\nif (buf.hasArray()) {\n    byte[] arr = buf.array();\n} else {\n    byte[] arr = new byte[buf.readableBytes()];\n    buf.getBytes(buf.readerIndex(), arr);\n}","typeGuard":"// Utility guard for any ByteBuf\nstatic byte[] arrayOrCopy(ByteBuf buf) {\n    if (buf.hasArray()) {\n        return buf.array();\n    }\n    byte[] copy = new byte[buf.readableBytes()];\n    buf.getBytes(buf.readerIndex(), copy);\n    return copy;\n}","tryCatchPattern":null,"preventionTips":["Never call array()/arrayOffset() without first checking hasArray().","Prefer nioBuffer() for portable byte access across heap and direct buffers.","Centralize array access in one helper to avoid scattered hasArray() checks."],"tags":["netty","buffer","direct-buffer","unsupported-operation"],"backgroundTag":null,"analyzedSha":"70040aacae241e9ba371e758f5b86e470bd77ad1","analyzedAt":"2026-08-14T01:29:15.551Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}