{"record":{"id":"c3b8cf7755f3a476","repo":"apache/flink","slug":"offset1-d-offset2-d-len-d-buffersize-d-add","errorCode":null,"errorMessage":"offset1=%d, offset2=%d, len=%d, bufferSize=%d, address1=%d, address2=%d","messagePattern":"offset1=(.+?), offset2=(.+?), len=(.+?), bufferSize=(.+?), address1=(.+?), address2=(.+?)","errorType":"exception","errorClass":"IndexOutOfBoundsException","httpStatus":null,"severity":"error","filePath":"flink-core/src/main/java/org/apache/flink/core/memory/MemorySegment.java","lineNumber":1595,"sourceCode":"                UNSAFE.copyMemory(\n                        this.heapMemory, thisPos, tempBuffer, BYTE_ARRAY_BASE_OFFSET, len);\n\n                // other -> this\n                UNSAFE.copyMemory(seg2.heapMemory, otherPos, this.heapMemory, thisPos, len);\n\n                // temp buffer -> other\n                UNSAFE.copyMemory(\n                        tempBuffer, BYTE_ARRAY_BASE_OFFSET, seg2.heapMemory, otherPos, len);\n                return;\n            } else if (this.address > this.addressLimit) {\n                throw new IllegalStateException(\"this memory segment has been freed.\");\n            } else if (seg2.address > seg2.addressLimit) {\n                throw new IllegalStateException(\"other memory segment has been freed.\");\n            }\n        }\n\n        // index is in fact invalid\n        throw new IndexOutOfBoundsException(\n                String.format(\n                        \"offset1=%d, offset2=%d, len=%d, bufferSize=%d, address1=%d, address2=%d\",\n                        offset1, offset2, len, tempBuffer.length, this.address, seg2.address));\n    }\n\n    /**\n     * Equals two memory segment regions.\n     *\n     * @param seg2 Segment to equal this segment with\n     * @param offset1 Offset of this segment to start equaling\n     * @param offset2 Offset of seg2 to start equaling\n     * @param length Length of the equaled memory region\n     * @return true if equal, false otherwise\n     */\n    public boolean equalTo(MemorySegment seg2, int offset1, int offset2, int length) {\n        int i = 0;\n\n        // we assume unaligned accesses are supported.","sourceCodeStart":1577,"sourceCodeEnd":1613,"githubUrl":"https://github.com/apache/flink/blob/2f3c205e9266cb30240eb7f4fdab15cad629a70f/flink-core/src/main/java/org/apache/flink/core/memory/MemorySegment.java#L1577-L1613","documentation":"MemorySegment.swapBytes(...) throws a formatted IndexOutOfBoundsException('offset1=%d, offset2=%d, len=%d, bufferSize=%d, address1=%d, address2=%d') when the requested regions are out of bounds on either segment and neither segment is freed. The message dumps every input plus both addresses so you can compare offset1+offset2+len against the actual segment limits.","triggerScenarios":"Calling swapBytes with offset1/offset2/len such that offset+len exceeds either segment's size (or a negative offset), while both segments are still alive — e.g. sort logic using a wrong entry size or misaligned index entries.","commonSituations":"Normalized-key or index-entry math drifting from the actual record layout after a schema/serializer change; swapping with a len computed for a different record width; off-by-one rollover when an entry spans the segment boundary.","solutions":["Decode the message: verify offset1 + len <= seg1.size() and offset2 + len <= seg2.size(); the mismatch points at which side's index math is wrong.","Re-derive len and offsets from the same entry-size constant used when records were written; check for schema/serializer version drift.","Add a bounds assert in your sort/swap loop during development to catch the bad entry before the swap."],"exampleFix":"// before\nseg1.swapBytes(seg2, tmp, off1, off2, len); // formatted IndexOutOfBoundsException\n\n// after\ncheckArgument(off1 >= 0 && off1 + len <= seg1.size(), \"bad offset1/len\");\ncheckArgument(off2 >= 0 && off2 + len <= seg2.size(), \"bad offset2/len\");\nseg1.swapBytes(seg2, tmp, off1, off2, len);","handlingStrategy":"validation","validationCode":"checkArgument(off1 >= 0 && off1 + len <= seg1.size(), \"offset1=%d len=%d size=%d\", off1, len, seg1.size());\ncheckArgument(off2 >= 0 && off2 + len <= seg2.size(), \"offset2=%d len=%d size=%d\", off2, len, seg2.size());","typeGuard":null,"tryCatchPattern":"try {\n    seg1.swapBytes(seg2, tempBuf, off1, off2, len);\n} catch (IndexOutOfBoundsException e) {\n    // message prints offset1/offset2/len/addresses; compare against segment sizes to find the bad side\n    throw e;\n}","preventionTips":["Derive offsets and len from one shared entry-size constant to prevent drift after serializer changes.","Log the formatted message verbatim — it contains every value needed to reconstruct the bug."],"tags":["memory","bounds-check","flink-core","sorting"],"backgroundTag":null,"analyzedSha":"2f3c205e9266cb30240eb7f4fdab15cad629a70f","analyzedAt":"2026-08-14T08:48:24.518Z","schemaVersion":2},"datasetVersion":"2026-08-14T10:17:34.591Z"}