alibaba/arthas · error · IllegalArgumentException

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

Error message

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

What it means

Thrown by resolveAllowedFile when a relative path cannot be matched against any configured allowed root directory. The tool resolves the path against each root in ARTHAS_MCP_VIEWFILE_ALLOWED_DIRS plus the defaults (arthas-output, ~/logs/), and rejects it if no candidate both exists and stays inside a root after symlink normalization (toRealPath). This guards against path-traversal and access outside whitelisted directories.

Source

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

            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;
        }
        throw new IllegalArgumentException("文件不存在或不在允许目录白名单内: " + requestedPath);
    }

    private static void assertRegularFile(Path file) {
        if (!Files.isRegularFile(file)) {
            throw new IllegalArgumentException("不是普通文件: " + file);
        }
    }

    private static boolean isUnderAllowedRoot(Path file, List<Path> allowedRoots) {
        for (Path root : allowedRoots) {
            if (file.startsWith(root)) {
                return true;
            }
        }
        return false;
    }

    private static int clampMaxBytes(Integer maxBytes) {

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Set ARTHAS_MCP_VIEWFILE_ALLOWED_DIRS=/your/dir to include the directory containing the target file (comma-separated for multiple).
  2. Verify the file actually exists: use an absolute path that is inside a configured root.
  3. Check for typos and stray '..' segments in the relative path.
  4. If defaults are expected, confirm arthas-output/ or ~/logs/ actually exist as directories in the JVM working directory.

Example fix

// before: file is outside all allowed roots
viewfile(path="/var/log/app.log")
// after: add the directory to the whitelist env var, then call
//   ARTHAS_MCP_VIEWFILE_ALLOWED_DIRS=/var/log
viewfile(path="/var/log/app.log")
Defensive patterns

Strategy: validation

Validate before calling

// Before calling viewfile, verify the path resolves under an allowed root
String allowedDirs = System.getenv("ARTHAS_MCP_VIEWFILE_ALLOWED_DIRS");
List<Path> roots = new ArrayList<>();
if (allowedDirs != null && !allowedDirs.isBlank()) {
    for (String d : allowedDirs.split(",")) {
        Path p = Paths.get(d.trim()).toAbsolutePath().normalize();
        if (Files.isDirectory(p)) roots.add(p.toRealPath());
    }
}
Path target = Paths.get(requestedPath);
if (!target.isAbsolute()) {
    boolean found = false;
    for (Path root : roots) {
        Path candidate = root.resolve(target).normalize();
        if (candidate.startsWith(root) && Files.exists(candidate)) { found = true; break; }
    }
    if (!found) throw new IllegalStateException("Path not under any allowed root: " + requestedPath);
} else {
    Path real = target.toRealPath();
    if (roots.stream().noneMatch(real::startsWith))
        throw new IllegalStateException("Path not under any allowed root: " + requestedPath);
}

Try / catch

// The tool itself wraps everything in try-catch (line 96-99) and returns
// a JSON error response string, so the MCP caller receives a string, not an exception.
// If calling resolveAllowedFile directly:
try {
    Path file = resolveAllowedFile(path, allowedRoots);
} catch (IllegalArgumentException e) {
    // handle: path not in whitelist or does not exist
    logger.warn("viewfile path rejected: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling the viewfile MCP tool with a relative path that (a) does not exist under any allowed root, (b) normalizes outside all roots via '..' segments, or (c) resolves through a symlink that escapes every root. The absolute-path branch (line 229-235) has a separate, slightly different message.

Common situations: ARTHAS_MCP_VIEWFILE_ALLOWED_DIRS env var is unset or misconfigured; the target file lives outside arthas-output or ~/logs/; a typo or wrong relative path; path traversal attempt like '../../etc/passwd'.

Related errors


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