{"record":{"id":"97e69a734205f585","repo":"quarkusio/quarkus","slug":"offset-count-offset-count-larger-than-fil-97e69a","errorCode":null,"errorMessage":"Offset + count (${offset + count}) larger than file size (${fileLength}): ${file}","messagePattern":"Offset \\+ count \\((.+?)\\) larger than file size \\((.+?)\\): (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/PathPart.java","lineNumber":50,"sourceCode":"     * @param offset The starting byte of the file (must be >= 0)\n     * @param count The number of bytes to send (must be >= 0 and offset+count <= file size)\n     */\n    public PathPart(Path file, long offset, long count) {\n        if (!Files.exists(file))\n            throw new IllegalArgumentException(\"File does not exist: \" + file);\n        if (!Files.isRegularFile(file))\n            throw new IllegalArgumentException(\"File is not a regular file: \" + file);\n        if (!Files.isReadable(file))\n            throw new IllegalArgumentException(\"File cannot be read: \" + file);\n        if (offset < 0)\n            throw new IllegalArgumentException(\"Offset (\" + offset + \") must be >= 0: \" + file);\n        if (count < 0)\n            throw new IllegalArgumentException(\"Count (\" + count + \") must be >= 0: \" + file);\n        long fileLength;\n        try {\n            fileLength = Files.size(file);\n            if ((offset + count) > fileLength)\n                throw new IllegalArgumentException(\n                        \"Offset + count (\" + (offset + count) + \") larger than file size (\" + fileLength + \"): \" + file);\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n        this.file = file;\n        this.offset = offset;\n        this.count = count;\n    }\n}\n","sourceCodeStart":32,"sourceCodeEnd":60,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/PathPart.java#L32-L60","documentation":"PathPart validates that the requested range fits within the file: `offset + count` must not exceed `Files.size(file)`. This IllegalArgumentException is thrown during construction when the byte range extends past the end of the file, ensuring the response never promises more bytes than the file contains.","triggerScenarios":"Calling `new PathPart(file, offset, count)` where offset+count > file size — commonly when the file shrank after its size was cached, or the range was computed against a different/older file, or an overflow made offset+count wrap (caught as too-large or negative count earlier).","commonSituations":"Caching `Files.size()` from a previous request while the file is being rewritten/truncated; serving files from a live log or rotating file; resume downloads where the server-side file changed between requests; using a stale Content-Length to compute the range.","solutions":["Re-read the file size immediately before constructing the part: `long size = Files.size(file); count = Math.min(count, size - offset);`","Return 416 Range Not Satisfiable when the requested range exceeds the current file size.","Avoid caching file sizes across requests for files that can change; or serve immutable snapshots (copy-on-write)."],"exampleFix":"// before\nlong size = cachedSize; // possibly stale\nPathPart part = new PathPart(file, offset, size - offset);\n// after\nlong size = Files.size(file);\nif (offset >= size) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}\nPathPart part = new PathPart(file, offset, Math.min(requestedCount, size - offset));","handlingStrategy":"validation","validationCode":"long fileSize = Files.size(file);\nif (offset >= fileSize) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}\nlong count = Math.min(requestedCount, fileSize - offset);","typeGuard":"boolean fitsInFile(long offset, long count, long fileSize) {\n    return offset >= 0 && count >= 0 && offset + count <= fileSize;\n}","tryCatchPattern":"try {\n    return Response.ok(new PathPart(file, offset, count)).build();\n} catch (IllegalArgumentException | IOException e) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}","preventionTips":["Always call Files.size(file) immediately before constructing PathPart; never cache sizes of mutable files.","Serve immutable snapshots if the file may be rewritten while clients hold ranges.","Clamp requested ranges to the current file size instead of rejecting trivially overshooting ranges."],"tags":["illegal-argument","filesystem","resteasy-reactive","range-request"],"backgroundTag":"invalid-range-request","analyzedSha":"e1c734241f34c7919086ceb4c9262b4a58f6de44","analyzedAt":"2026-09-05T17:01:29.979Z","contentChangedAt":"2026-09-05T17:01:29.979Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}