quarkusio/quarkus · error · IllegalArgumentException
Path leaves the application root: <file>
Error message
Path leaves the application root: <file>
What it means
During validation, if a path component exists and its real path does not start with the real application root, the resolved path is judged to escape the root via a real-path alias (e.g. a bind mount or hard link to outside), and this IllegalArgumentException is thrown. It complements the lexical .. check by catching physical escapes.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java:487
}
private static void validateExistingPathComponents(Path normalizedRoot, Path resolved, String file) {
final Path realRoot;
try {
realRoot = normalizedRoot.toRealPath();
} catch (IOException e) {
throw new IllegalArgumentException("Unable to validate the application root for remote-dev path: " + file, e);
}
Path current = normalizedRoot;
for (Path element : normalizedRoot.relativize(resolved)) {
current = current.resolve(element);
if (Files.isSymbolicLink(current)) {
throw new IllegalArgumentException("Symbolic links are not allowed in remote-dev paths: " + file);
}
if (Files.exists(current, LinkOption.NOFOLLOW_LINKS)) {
try {
if (!current.toRealPath().startsWith(realRoot)) {
throw new IllegalArgumentException("Path leaves the application root: " + file);
}
} catch (IOException e) {
throw new IllegalArgumentException("Unable to validate remote-dev path: " + file, e);
}
} else {
break;
}
}
}
private static String normalizeFile(String file) {
requireNonNull(file, "file");
file = file.replace('\\', '/');
if (file.startsWith("/")) {
file = file.substring(1);
}
return file;
}View on GitHub (pinned to e1c734241f)
Solutions
- Ensure all paths under the application root are physically inside it (no nested bind mounts for the sync path).
- Use consistent canonical paths when mounting volumes into dev containers.
- Move the synced output directory so its real path is within the root.
- Run remote-dev server and client against the same canonical filesystem layout.
Example fix
# before: docker -v /elsewhere/classes:/app/target/classes (real path leaves root) # after: build into a directory physically under the app root, no nested bind mount
Defensive patterns
Strategy: validation
Validate before calling
Path root = Path.of(".").toAbsolutePath().normalize().toRealPath();
Path target = root.resolve(relPath).normalize();
if (Files.exists(target, LinkOption.NOFOLLOW_LINKS) && !target.toRealPath().startsWith(root))
throw new IllegalStateException("target real path escapes root: " + target); Try / catch
try {
client.sync(path);
} catch (IllegalArgumentException e) {
if (e.getMessage().startsWith("Path leaves the application root")) {
log.errorf("%s resolves outside the app root (bind mount or link) — fix mounts", path);
} else throw e;
} Prevention
- Avoid nested bind mounts inside the project root
- Use canonical paths for container volume mounts
- Verify with `realpath` that all synced paths stay under the root
When it happens
Trigger: updateFile or resolveApplicationPath where an existing component of the path resolves (via toRealPath) outside the real application root — bind mounts, mounts overlapping the root, or links resolved by the OS.
Common situations: Application root contains an overlay/bind-mounted subdirectory; Docker volume mounts nested inside the project dir; network mounts aliased under a different canonical path.
Related errors
- Path is not below the application root: <file>
- IOException (wrapped)
- Unable to validate the application root for remote-dev path:
- Symbolic links are not allowed in remote-dev paths: <file>
- Unable to validate remote-dev path: <file>
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/9dc0837bba640118.
Report an issue: GitHub.