quarkusio/quarkus · error · IllegalArgumentException
File cannot be read: ${file}
Error message
File cannot be read: ${file} What it means
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).
Source
Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/PathPart.java:41
/**
* The number of bytes to send
*/
public final long count;
/**
* Create a new partial {@link Path} object.
*
* @param file The file to send
* @param offset The starting byte of the file (must be >= 0)
* @param count The number of bytes to send (must be >= 0 and offset+count <= file size)
*/
public PathPart(Path file, long offset, long count) {
if (!Files.exists(file))
throw new IllegalArgumentException("File does not exist: " + file);
if (!Files.isRegularFile(file))
throw new IllegalArgumentException("File is not a regular file: " + file);
if (!Files.isReadable(file))
throw new IllegalArgumentException("File cannot be read: " + file);
if (offset < 0)
throw new IllegalArgumentException("Offset (" + offset + ") must be >= 0: " + file);
if (count < 0)
throw new IllegalArgumentException("Count (" + count + ") must be >= 0: " + file);
long fileLength;
try {
fileLength = Files.size(file);
if ((offset + count) > fileLength)
throw new IllegalArgumentException(
"Offset + count (" + (offset + count) + ") larger than file size (" + fileLength + "): " + file);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
this.file = file;
this.offset = offset;
this.count = count;
}
}View on GitHub (pinned to e1c734241f)
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.
Example fix
// before
Path file = Path.of(uploadsDir, id);
return Response.ok(new PathPart(file, 0, Files.size(file))).build();
// after
Path file = Path.of(uploadsDir, id);
if (!Files.isReadable(file)) {
return Response.status(Response.Status.FORBIDDEN).build();
}
return Response.ok(new PathPart(file, 0, Files.size(file))).build(); Defensive patterns
Strategy: validation
Validate before calling
if (!Files.isReadable(file)) {
return Response.status(Response.Status.FORBIDDEN).build();
} Type guard
boolean isReadableFile(Path p) {
return p != null && Files.isRegularFile(p) && Files.isReadable(p);
} Try / catch
try {
return Response.ok(new PathPart(file, 0, Files.size(file))).build();
} catch (IllegalArgumentException e) {
LOG.errorf("Cannot serve unreadable file %s", file);
return Response.status(Response.Status.FORBIDDEN).build();
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.
Related errors
- File does not exist: ${file}
- File is not a regular file: ${file}
- Offset + count (${offset + count}) larger than file size (${
- Failed to restore the timestamp of the file:
- Failed to create ${classesDir}
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/ac4536ef64591f17.
Report an issue: GitHub.