quarkusio/quarkus · error · IllegalArgumentException

Symbolic links are not allowed in remote-dev paths: <file>

Error message

Symbolic links are not allowed in remote-dev paths: <file>

What it means

For each path component of the resolved remote-dev file, validateExistingPathComponents rejects the path if any element is a symbolic link. Symbolic links could redirect writes outside the application root, so remote-dev sync refuses them outright with this IllegalArgumentException.

Source

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

                || 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);
            }
            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('\\', '/');

View on GitHub (pinned to e1c734241f)

Solutions

  1. Replace symlinked directories under the application root with real directories (cp -rL, then delete the link).
  2. Run the dev server from a real path (use the resolved path, e.g. /private/var/... instead of /var/... on macOS).
  3. Configure your build to output classes to a non-symlinked directory.
  4. If a symlink is unavoidable, use local dev mode instead of remote-dev sync for that layout.

Example fix

# before: target/classes -> /mnt/shared/classes (symlink)
# after
cp -rL target/classes target/classes.real && rm target/classes && mv target/classes.real target/classes
Defensive patterns

Strategy: validation

Validate before calling

Path root = Path.of(".").toAbsolutePath().normalize();
Path target = root.resolve(relPath).normalize();
for (Path cur = root; cur.getNameCount() <= target.getNameCount(); ) {
    if (Files.isSymbolicLink(cur)) throw new IllegalStateException("symlink not allowed: " + cur);
    if (cur.equals(target)) break;
    cur = cur.resolve(target.getName(root.relativize(cur).getNameCount()));
}

Type guard

boolean hasNoSymlinks(Path root, Path target) throws IOException {
    Path cur = root;
    for (Path el : root.relativize(target.normalize())) {
        cur = cur.resolve(el);
        if (Files.isSymbolicLink(cur)) return false;
    }
    return true;
}

Try / catch

try {
    client.sync(path);
} catch (IllegalArgumentException e) {
    if (e.getMessage().startsWith("Symbolic links are not allowed")) {
        log.errorf("%s contains a symlink — replace with a real directory", path);
    } else throw e;
}

Prevention

When it happens

Trigger: updateFile or resolveApplicationPath encountering any symlink component under the application root (e.g. target/classes is a symlink, or the file itself is a symlink).

Common situations: Projects using symlinked source/output dirs (common with some build setups or Dropbox-synced folders); macOS /tmp symlink when running from /tmp; container image layouts using symlinks.

Related errors


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