{"record":{"id":"ac4536ef64591f17","repo":"quarkusio/quarkus","slug":"file-cannot-be-read-file-ac4536","errorCode":null,"errorMessage":"File cannot be read: ${file}","messagePattern":"File cannot be read: (.+?)","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":41,"sourceCode":"    /**\n     * The number of bytes to send\n     */\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}","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/quarkusio/quarkus/blob/e1c734241f34c7919086ceb4c9262b4a58f6de44/independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/PathPart.java#L23-L59","documentation":"PathPart requires the file to be readable by the current process so the response can stream its bytes. This IllegalArgumentException is thrown when the file exists and is a regular file but the JVM lacks read permission (POSIX permissions, ACLs, or sandbox/SELinux restrictions).","triggerScenarios":"Calling `new PathPart(file, offset, count)` where `Files.isReadable(file)` is false — e.g. file owned by another user with 0600 permissions, or the container runs as a non-root user without access to a mounted volume file.","commonSituations":"Files written by root on a shared volume but served by a container running as user 1001; strict umask after processing uploads; read-only mounted secret files with wrong ownership; SELinux/AppArmor denials in hardened deployments.","solutions":["Fix file permissions/ownership so the Quarkus process user can read the file (chmod/chown or correct volume securityContext).","Check `Files.isReadable(file)` before constructing PathPart and return 403 to the client if not readable.","Run the container with the same user/uid that owns the file, or write served files with world/group-readable permissions at creation time.","Inspect denial logs (SELinux audit, container runtime) if permissions look correct but reads still fail."],"exampleFix":"// before\nPath file = Path.of(uploadsDir, id);\nreturn Response.ok(new PathPart(file, 0, Files.size(file))).build();\n// after\nPath file = Path.of(uploadsDir, id);\nif (!Files.isReadable(file)) {\n    return Response.status(Response.Status.FORBIDDEN).build();\n}\nreturn Response.ok(new PathPart(file, 0, Files.size(file))).build();","handlingStrategy":"validation","validationCode":"if (!Files.isReadable(file)) {\n    return Response.status(Response.Status.FORBIDDEN).build();\n}","typeGuard":"boolean isReadableFile(Path p) {\n    return p != null && Files.isRegularFile(p) && Files.isReadable(p);\n}","tryCatchPattern":"try {\n    return Response.ok(new PathPart(file, 0, Files.size(file))).build();\n} catch (IllegalArgumentException e) {\n    LOG.errorf(\"Cannot serve unreadable file %s\", file);\n    return Response.status(Response.Status.FORBIDDEN).build();\n}","preventionTips":["Align the container's run-as user with the ownership of served files (Dockerfile USER / k8s securityContext).","Create served files with group/world-readable mode (e.g. set POSIX permissions at write time).","Check permissions inside the actual runtime environment (volumes, secrets), not just on your dev machine."],"tags":["filesystem","permissions","illegal-argument","resteasy-reactive"],"backgroundTag":"permission-denied","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"}