{"record":{"id":"97d428b0ed659b91","repo":"hibernate/hibernate-orm","slug":"the-required-offset-is-beyond-page-capacity","errorCode":null,"errorMessage":"The required offset is beyond page capacity","messagePattern":"The required offset is beyond page capacity","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"hibernate-core/src/main/java/org/hibernate/internal/util/collections/AbstractPagedArray.java","lineNumber":54,"sourceCode":"\t\t/**\n\t\t * Clears the contents of the page.\n\t\t */\n\t\tpublic void clear() {\n\t\t\t// We need to null out everything to prevent GC nepotism (see https://hibernate.atlassian.net/browse/HHH-19047)\n\t\t\tArrays.fill( elements, 0, lastNotEmptyOffset + 1, null );\n\t\t\tlastNotEmptyOffset = -1;\n\t\t}\n\n\t\t/**\n\t\t * Set the provided element at the specified offset.\n\t\t *\n\t\t * @param offset the offset in the page where to set the element\n\t\t * @param element the element to set\n\t\t * @return the previous element at {@code offset} if one existed, or {@code null}\n\t\t */\n\t\tpublic E set(int offset, Object element) {\n\t\t\tif ( offset >= PAGE_CAPACITY ) {\n\t\t\t\tthrow new IllegalArgumentException( \"The required offset is beyond page capacity\" );\n\t\t\t}\n\t\t\tfinal Object old = elements[offset];\n\t\t\tif ( element != null ) {\n\t\t\t\tif ( offset > lastNotEmptyOffset ) {\n\t\t\t\t\tlastNotEmptyOffset = offset;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( lastNotEmptyOffset == offset && old != null ) {\n\t\t\t\t// must search backward for the first not empty offset\n\t\t\t\tint i = offset;\n\t\t\t\tfor ( ; i >= 0; i-- ) {\n\t\t\t\t\tif ( elements[i] != null ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastNotEmptyOffset = i;\n\t\t\t}\n\t\t\telements[offset] = element;","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/hibernate/hibernate-orm/blob/fad1729dce015f908198d57a8d80274a30f905a5/hibernate-core/src/main/java/org/hibernate/internal/util/collections/AbstractPagedArray.java#L36-L72","documentation":"AbstractPagedArray stores elements in fixed-size Page objects; Page.set(offset, element) hard-rejects any offset >= PAGE_CAPACITY with IllegalArgumentException. This is an internal invariant guard: callers are expected to translate an absolute index into (page, pageOffset) via toPageOffset(index). Seeing it means offset math in the calling code is wrong (e.g. an absolute index was passed where a within-page offset was expected).","triggerScenarios":"Subclassing AbstractPagedArray (InstanceIdentityMap and InstanceIdentityStore do) and calling page.set(...) with an absolute index instead of toPageOffset(index); or computing page offsets with a different page size assumption than PAGE_CAPACITY.","commonSituations":"Almost never seen by Hibernate users — it guards internal persistence-context storage. It appears when extending or copying the paged-array code and getting the paging arithmetic wrong, typically off-by-PAGE_CAPACITY errors.","solutions":["Pass toPageOffset(absoluteIndex) as the offset, never the absolute index","Add an assertion offset < PAGE_CAPACITY next to every page.set call during development","Write a unit test that fills past one page boundary (index == PAGE_CAPACITY) to catch paging math early"],"exampleFix":"// before: absolute index leaks into the page call\npage.set( index, element );\n// after: translate to within-page offset first\nfinal Page<E> page = getOrCreatePage( index );\npage.set( toPageOffset( index ), element );","handlingStrategy":"validation","validationCode":"// Always derive the page offset; never pass absolute indexes to a Page\nint pageOffset = toPageOffset( absoluteIndex );\nassert pageOffset >= 0 && pageOffset < PAGE_CAPACITY;\npage.set( pageOffset, element );","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never call Page.set/get directly with absolute indexes — go through the AbstractPagedArray API that does the math","When subclassing, re-use toPageOffset/getPage rather than reimplementing paging arithmetic","Unit-test crossing page boundaries whenever you touch this code"],"tags":["hibernate","internal","collections","index-out-of-bounds","invariant"],"backgroundTag":"index-out-of-bounds","analyzedSha":"fad1729dce015f908198d57a8d80274a30f905a5","analyzedAt":"2026-08-22T04:13:57.527Z","schemaVersion":2},"datasetVersion":"2026-08-22T09:17:25.309Z"}