apache/cassandra · error · IllegalArgumentException
Illegal file to fetch:
Error message
Illegal file to fetch:
What it means
AsyncProfilerService.fetch reads a previously generated profiling result file from the profiles log directory. To prevent path traversal it resolves the requested file and requires that its absolute parent equals the log directory; anything escaping that directory (e.g. '../secrets') is rejected with this IllegalArgumentException.
Source
Thrown at src/java/org/apache/cassandra/service/AsyncProfilerService.java:349
try
{
maybeCreateProfilesLogDir();
return Arrays.stream(new File(logDir).list()).map(File::name).sorted().collect(toList());
}
catch (Throwable t)
{
return List.of();
}
}
@Override
public byte[] fetch(String resultFile) throws IOException
{
try
{
if (!Path.of(logDir, resultFile).toAbsolutePath().getParent().equals(Path.of(logDir)))
{
throw new IllegalArgumentException("Illegal file to fetch: " + resultFile);
}
maybeCreateProfilesLogDir();
return Files.readAllBytes(new File(logDir, resultFile).toPath());
}
catch (NoSuchFileException t)
{
logger.error("Result file " + resultFile + " not found or error occurred while returning it.", t);
throw t;
}
}
@Override
public void purge()
{
maybeCreateProfilesLogDir();
new File(logDir).deleteRecursive();
}
View on GitHub (pinned to 88fd0f6a0e)
Solutions
- Pass only the plain file name as returned by the list() operation, with no slashes or '..' segments
- List available results via the list() MBean operation and pick a name from it
- Verify Path.of(logDir, name).toAbsolutePath().getParent() equals the log dir before calling
Example fix
// before
byte[] data = service.fetch("../heap.dump");
// after
String name = (String) service.list().stream().filter(f -> f.endsWith(".html")).findFirst().get();
byte[] data = service.fetch(name); Defensive patterns
Strategy: validation
Validate before calling
Path expected = Path.of(logDir).toAbsolutePath();
Path resolved = Path.of(logDir, name).toAbsolutePath();
if (!expected.equals(resolved.getParent())) throw new IllegalArgumentException("file must be a bare name inside the log dir"); Try / catch
try { return svc.fetch(name); } catch (IllegalArgumentException e) { if (e.getMessage().startsWith("Illegal file to fetch")) return null; throw e; } Prevention
- Only fetch names returned by list()
- Never interpolate user input into the file name
- Reject any name containing '/', '\\', or '..' before calling
When it happens
Trigger: Calling fetch("somefile") where the resolved path's parent is not the profiles log dir — e.g. fetch("../cassandra.yaml"), absolute paths, or names containing path separators.
Common situations: Tooling concatenating user input into the file name; attempting to download non-profile files through the profiling MBean; passing names produced by a different Cassandra version with different log dir layout.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Access denied
- Access Denied
- Access is denied!
- The arbitrary command execution is not permitted with %s MBe
- Can't enable audit log archiving via nodetool unless audit_l
AI-assisted analysis of apache/cassandra@88fd0f6a0e (2026-09-10).
Data as JSON: /api/errors/04581d7e593ad9ea.
Report an issue: GitHub.