{"record":{"id":"8e05beb768356b75","repo":"quarkusio/quarkus","slug":"offset-offset-must-be-0-file-8e05be","errorCode":null,"errorMessage":"Offset (${offset}) must be >= 0: ${file}","messagePattern":"Offset \\((.+?)\\) must be >= 0: (.+?)","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":43,"sourceCode":"     */\n    public final long count;\n\n    /**\n     * Create a new partial {@link Path} object.\n     *\n     * @param file The file to send\n     * @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":25,"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#L25-L60","documentation":"PathPart models a byte range [offset, offset+count) of a file. The constructor rejects a negative offset with this IllegalArgumentException, since a negative start position has no meaning for a file range.","triggerScenarios":"Calling `new PathPart(file, offset, count)` with `offset < 0`, typically when offset comes from parsing a client's Range header (e.g. `bytes=-500`) or from an unchecked numeric field.","commonSituations":"Parsing partial Range headers where the start value is absent and a sentinel -1 is passed through; integer underflow computing offsets; client-supplied offsets not validated in custom range-handling code.","solutions":["Clamp or reject negative offsets before construction: `if (offset < 0) offset = 0;` or return 416 Range Not Satisfiable.","When parsing Range headers, treat suffix ranges (`bytes=-N`) explicitly instead of passing -1 as the start.","Validate numeric inputs from client requests before using them as offsets."],"exampleFix":"// before\nlong start = parseRangeStart(header); // may be -1\nPathPart part = new PathPart(file, start, count);\n// after\nlong start = parseRangeStart(header);\nif (start < 0) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}\nPathPart part = new PathPart(file, start, count);","handlingStrategy":"validation","validationCode":"if (offset < 0) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}","typeGuard":"boolean isValidStart(long offset) {\n    return offset >= 0;\n}","tryCatchPattern":"try {\n    return Response.ok(new PathPart(file, offset, count)).build();\n} catch (IllegalArgumentException e) {\n    return Response.status(Response.Status.REQUESTED_RANGE_NOT_SATISFIABLE).build();\n}","preventionTips":["Parse Range headers with a vetted parser; handle suffix ranges (bytes=-N) explicitly.","Clamp parsed offsets to [0, fileSize) before use.","Never propagate sentinel values like -1 into range arithmetic."],"tags":["illegal-argument","validation","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"}