{"record":{"id":"dcb1125995c5034f","repo":"apache/flink","slug":"the-given-buffer-is-neither-an-array-backed-heap-b","errorCode":null,"errorMessage":"The given buffer is neither an array-backed heap ByteBuffer, nor a direct ByteBuffer.","messagePattern":"The given buffer is neither an array-backed heap ByteBuffer, nor a direct ByteBuffer\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/core/memory/DataInputDeserializer.java","lineNumber":80,"sourceCode":"    // ------------------------------------------------------------------------\n    //  Changing buffers\n    // ------------------------------------------------------------------------\n\n    public void setBuffer(@Nonnull ByteBuffer buffer) {\n        if (buffer.hasArray()) {\n            this.buffer = buffer.array();\n            this.position = buffer.arrayOffset() + buffer.position();\n            this.end = this.position + buffer.remaining();\n        } else if (buffer.isDirect() || buffer.isReadOnly()) {\n            // TODO: FLINK-8585 handle readonly and other non array based buffers more efficiently\n            // without data copy\n            this.buffer = new byte[buffer.remaining()];\n            this.position = 0;\n            this.end = this.buffer.length;\n\n            buffer.get(this.buffer);\n        } else {\n            throw new IllegalArgumentException(\n                    \"The given buffer is neither an array-backed heap ByteBuffer, nor a direct ByteBuffer.\");\n        }\n    }\n\n    public void setBuffer(@Nonnull byte[] buffer, int start, int len) {\n\n        if (start < 0 || len < 0 || start + len > buffer.length) {\n            throw new IllegalArgumentException(\"Invalid bounds.\");\n        }\n\n        setBufferInternal(buffer, start, len);\n    }\n\n    public void setBuffer(@Nonnull byte[] buffer) {\n        setBufferInternal(buffer, 0, buffer.length);\n    }\n\n    private void setBufferInternal(@Nonnull byte[] buffer, int start, int len) {","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/core/memory/DataInputDeserializer.java#L62-L98","documentation":"Thrown as an IllegalArgumentException by DataInputDeserializer.setBuffer(ByteBuffer) when the buffer is neither array-backed (hasArray()==false) nor direct/read-only. This is the else branch after checking hasArray() and (isDirect()||isReadOnly()); it catches ByteBuffer instances that are views or wrappers without an accessible backing array and without the direct or read-only flag — a rare combination that the deserializer cannot efficiently read.","triggerScenarios":"Constructing a DataInputDeserializer or calling setBuffer with a ByteBuffer that is a sliced/duplicated view of a non-direct buffer whose hasArray() returns false, or a custom ByteBuffer subclass not flagged direct or read-only.","commonSituations":"Passing a ByteBuffer obtained from NIO channel operations or third-party libraries that create non-array-backed, non-direct buffers; custom ByteBuffer implementations; edge cases with memory-mapped buffers on some JVMs.","solutions":["Convert the ByteBuffer to a heap array before passing: copy bytes via buffer.get(byte[]) into a fresh byte[] and use the byte[] constructor.","Ensure the ByteBuffer is direct (ByteBuffer.allocateDirect) or array-backed (ByteBuffer.allocate) if you want zero-copy.","If the buffer is a view, call .duplicate() on an array-backed source or re-allocate."],"exampleFix":"// before\nDataInputDeserializer in = new DataInputDeserializer(weirdByteBuffer);\n\n// after — copy to a heap array first\nbyte[] bytes = new byte[weirdByteBuffer.remaining()];\nweirdByteBuffer.get(bytes);\nDataInputDeserializer in = new DataInputDeserializer(bytes);","handlingStrategy":"validation","validationCode":"if (!buffer.hasArray() && !buffer.isDirect() && !buffer.isReadOnly()) {\n    // copy to heap array to satisfy DataInputDeserializer\n    byte[] bytes = new byte[buffer.remaining()];\n    buffer.get(bytes);\n    new DataInputDeserializer(bytes);\n}","typeGuard":"buffer.hasArray() || buffer.isDirect() || buffer.isReadOnly()","tryCatchPattern":null,"preventionTips":["Prefer ByteBuffer.allocate (array-backed) or ByteBuffer.allocateDirect (direct) when creating buffers for DataInputDeserializer.","Copy non-standard buffers to a heap byte[] before constructing the deserializer.","Avoid passing custom ByteBuffer subclasses without array or direct backing."],"tags":["memory","deserialization","bytebuffer","api-misuse"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}