quarkusio/quarkus · error · IllegalArgumentException

Path is not below the application root: <file>

Error message

Path is not below the application root: <file>

What it means

resolveApplicationPath validates that a file path sent by a remote dev client resolves strictly inside the application root. If the path is absolute, equals the root, escapes the root (e.g. via ..), or looks like a Windows drive path (second char ':'), it throws this IllegalArgumentException. This is a path-traversal guard for remote dev mode.

Source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/dev/RuntimeUpdatesProcessor.java:465

    @Override
    public void deleteFile(String file) {
        Path resolve = resolveApplicationPath(file);
        try {
            Files.deleteIfExists(resolve);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private Path resolveApplicationPath(String file) {
        file = normalizeFile(file);
        Path normalizedRoot = applicationRoot.toAbsolutePath().normalize();
        Path relativePath = Path.of(file);
        Path resolved = normalizedRoot.resolve(relativePath).normalize();
        if (relativePath.isAbsolute() || resolved.equals(normalizedRoot) || !resolved.startsWith(normalizedRoot)
                || file.length() >= 2 && file.charAt(1) == ':') {
            throw new IllegalArgumentException("Path is not below the application root: " + file);
        }
        validateExistingPathComponents(normalizedRoot, resolved, file);
        return resolved;
    }

    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);
            }

View on GitHub (pinned to e1c734241f)

Solutions

  1. Send paths relative to the application root (e.g. com/example/Foo.class, not /full/path/com/example/Foo.class).
  2. Normalize the client path against its own project root before sending.
  3. Remove any drive-letter prefixes or leading slashes from the sync payload.
  4. If you are not intentionally using remote-dev sync, check that quarkus.live-reload / remote-dev is not exposed unintentionally.

Example fix

// client: before
remoteClient.send("/home/me/app/target/classes/com/App.class");
// after
remoteClient.send("com/App.class"); // relative to application root
Defensive patterns

Strategy: validation

Validate before calling

String safe(String file) {
    Path p = Path.of(file);
    if (p.isAbsolute() || file.contains("..") || (file.length() >= 2 && file.charAt(1) == ':'))
        throw new IllegalArgumentException("must be root-relative: " + file);
    return file;
}

Type guard

boolean isSafeRelativePath(String file) {
    if (file == null || file.isEmpty()) return false;
    Path p = Path.of(file);
    return !p.isAbsolute() && !file.contains("..")
        && !(file.length() >= 2 && file.charAt(1) == ':');
}

Try / catch

try {
    client.sync(path);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Path is not below the application root")) {
        log.errorf("Client sent non-relative path %s — normalize against project root", path);
    } else throw e;
}

Prevention

When it happens

Trigger: Calling updateFile/deleteFile (via resolve) with a path that is absolute (/etc/passwd), contains ../ escaping the root, is exactly the application root, or has a form like C:\foo.

Common situations: Misconfigured remote client sending absolute paths instead of root-relative ones; a buggy client normalizing to absolute paths; an attacker probing the sync endpoint (this error is the guard working).

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/595bea83765b9e50. Report an issue: GitHub.