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
- Add the parent directory of the target file to the ARTHAS_VIEWFILE_ALLOWED_DIRS env var (comma-separated) before starting arthas, then retry.
- Move/copy the file under an already-allowed root (arthas-output/ or ~/logs/).
- Use a relative path that resolves under an allowed root instead of an absolute one.
- 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
- Configure ARTHAS_VIEWFILE_ALLOWED_DIRS to include the directories you need to read.
- Prefer relative paths under an existing allowed root (arthas-output/, ~/logs/).
- Remember toRealPath follows symlinks, so symlink targets must also be under an allowed root.
- Set the env var before launching arthas; it is read at tool initialisation.
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.