alibaba/arthas · error · IllegalArgumentException

文件不在允许目录白名单内: ${requestedPath}

Error message

文件不在允许目录白名单内: ${requestedPath}

What it means

Thrown by resolveAllowedFile() in the ViewFile MCP tool when the requested absolute path resolves (via toRealPath, following symlinks) to a file that is not located under any configured allowed root directory. This is the whitelist boundary: viewfile only reads from roots in the ARTHAS_VIEWFILE_ALLOWED_DIRS env var plus the default roots (arthas-output/, ~/logs/).

Source

Thrown at core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/ViewFileTool.java:233

        return deduplicate(roots);
    }

    private static List<Path> deduplicate(List<Path> roots) {
        if (roots == null || roots.isEmpty()) {
            return Collections.emptyList();
        }
        LinkedHashSet<Path> set = new LinkedHashSet<>(roots);
        return new ArrayList<>(set);
    }

    private Path resolveAllowedFile(String requestedPath, List<Path> allowedRoots) throws Exception {
        Path req = Paths.get(requestedPath);
        if (req.isAbsolute()) {
            Path real = req.toRealPath();
            assertRegularFile(real);
            if (!isUnderAllowedRoot(real, allowedRoots)) {
                throw new IllegalArgumentException("文件不在允许目录白名单内: " + requestedPath);
            }
            return real;
        }

        for (Path root : allowedRoots) {
            Path candidate = root.resolve(req).normalize();
            if (!candidate.startsWith(root)) {
                continue;
            }
            if (!Files.exists(candidate)) {
                continue;
            }
            Path real = candidate.toRealPath();
            if (!real.startsWith(root)) {
                continue;
            }
            assertRegularFile(real);
            return real;

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Add the parent directory of the target file to the ARTHAS_VIEWFILE_ALLOWED_DIRS env var (comma-separated) before starting arthas, then retry.
  2. Move/copy the file under an already-allowed root (arthas-output/ or ~/logs/).
  3. Use a relative path that resolves under an allowed root instead of an absolute one.
  4. Confirm the resolved real path (after symlinks) is actually under a configured root.

Example fix

// before
viewfile(path="/etc/myapp/config.yaml")
// after
// export ARTHAS_VIEWFILE_ALLOWED_DIRS=/etc/myapp before launching arthas
viewfile(path="/etc/myapp/config.yaml")
Defensive patterns

Strategy: validation

Validate before calling

// Verify the target resolves under an allowed root before calling viewfile
Path real = Paths.get(requestedPath).toRealPath();
boolean allowed = loadAllowedRoots().stream().anyMatch(root -> real.startsWith(root));
if (!allowed) throw new IllegalArgumentException("path outside allowed roots: " + requestedPath);

Type guard

static boolean isUnderAllowedRoot(Path file, List<Path> roots) {
    Path real;
    try { real = file.toRealPath(); } catch (IOException e) { return false; }
    return roots.stream().anyMatch(root -> real.startsWith(root));
}

Try / catch

null

Prevention

When it happens

Trigger: Calling viewfile with an absolute path outside every allowed root, e.g. path=/etc/passwd when no allowed root covers /etc. toRealPath resolves symlinks before the check, so symlink escapes are also caught.

Common situations: Trying to read a log/config file outside the default roots without configuring ARTHAS_VIEWFILE_ALLOWED_DIRS; symlink pointing outside the allowed tree; expecting arthas-output or ~/logs to cover a path it does not.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/3db95d9d5259b594. Report an issue: GitHub.