alibaba/arthas · critical · IllegalStateException
Failed to prepare MCP upload directory
Error message
Failed to prepare MCP upload directory
What it means
prepareUploadRoot wraps any IOException during upload directory setup (createDirectories, toRealPath, setDirectoryPermissions) into an IllegalStateException. This occurs during UploadFileTool construction (constructor line 67), not during individual file uploads. The constructor rejects symlinks, non-directory paths, and permission failures.
Source
Thrown at core/src/main/java/com/taobao/arthas/core/mcp/tool/function/basic1000/UploadFileTool.java:362
private static Path prepareUploadRoot(Path root) {
if (root == null) {
throw new IllegalArgumentException("uploadRoot must not be null");
}
try {
Path normalized = root.toAbsolutePath().normalize();
if (Files.isSymbolicLink(normalized)) {
throw new IllegalArgumentException("uploadRoot must not be a symbolic link");
}
Files.createDirectories(normalized);
if (!Files.isDirectory(normalized, LinkOption.NOFOLLOW_LINKS)) {
throw new IllegalArgumentException("uploadRoot must be a directory");
}
Path realRoot = normalized.toRealPath();
setDirectoryPermissions(realRoot);
return realRoot;
} catch (IOException e) {
throw new IllegalStateException("Failed to prepare MCP upload directory", e);
}
}
private static Path createDefaultUploadRoot() {
try {
return Files.createTempDirectory("arthas-mcp-uploads-");
} catch (IOException e) {
throw new IllegalStateException("Failed to create MCP upload directory", e);
}
}
private static void setDirectoryPermissions(Path directory) throws IOException {
try {
Files.setPosixFilePermissions(directory, DIRECTORY_PERMISSIONS);
} catch (UnsupportedOperationException ignored) {
// 当前文件系统不支持 POSIX 权限。
}
}View on GitHub (pinned to 21cf2e9ba5)
Solutions
- Ensure the upload root path is creatable and writable by the JVM process.
- Check that no regular file occupies the path or any required parent.
- Verify the path is not a symlink (symlinks are explicitly rejected).
- Remove the custom uploadRoot and let the tool use the default temp directory.
- Fix filesystem permissions or mount the target volume read-write.
Example fix
// before: custom root on a read-only mount or occupied by a file
new UploadFileTool(Paths.get("/readonly/uploads"), ...)
// after: use a writable path or the default constructor
new UploadFileTool() // uses Files.createTempDirectory automatically Defensive patterns
Strategy: try-catch
Validate before calling
// Before constructing UploadFileTool with a custom root, verify the path
Path root = customUploadRoot.toAbsolutePath().normalize();
if (Files.isSymbolicLink(root)) {
throw new IllegalArgumentException("uploadRoot must not be a symbolic link");
}
Files.createDirectories(root);
if (!Files.isDirectory(root, LinkOption.NOFOLLOW_LINKS)) {
throw new IllegalArgumentException("uploadRoot must be a directory");
}
if (!Files.isWritable(root)) {
throw new IllegalArgumentException("uploadRoot is not writable: " + root);
} Try / catch
try {
UploadFileTool tool = new UploadFileTool(uploadRoot, maxFileBytes, maxTotalBytes);
} catch (IllegalStateException e) {
if (e.getMessage().equals("Failed to prepare MCP upload directory")) {
// IO failure during upload directory setup — check permissions, disk, symlinks
logger.error("Upload root setup failed", e.getCause());
}
} Prevention
- Verify the upload root path is writable and not a symlink before constructing UploadFileTool.
- Ensure no regular file occupies the target path or any parent.
- Prefer the default constructor (temp directory) if no specific upload root is required.
- Run a write-test on the directory before application startup.
When it happens
Trigger: Constructing UploadFileTool with a custom uploadRoot path where Files.createDirectories fails, toRealPath fails, or the normalized path is a symlink or not a directory. Also triggered if setDirectoryPermissions hits an IOException (not just UnsupportedOperationException).
Common situations: Configured upload path is on a read-only filesystem; a parent path component is a regular file not a directory; insufficient OS permissions; disk full; the path is a symlink (rejected at line 351-353).
Related errors
- Failed to create MCP upload directory
- File '{file}' exists but is a directory
- File '{file}' cannot be written to
- Directory '{parent}' could not be created
- Bad zip entry: {currentEntry}
AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14).
Data as JSON: /api/errors/f23b76160a7d1218.
Report an issue: GitHub.