alibaba/arthas · critical · IllegalStateException

Failed to create MCP upload directory

Error message

Failed to create MCP upload directory

What it means

createDefaultUploadRoot fails when Files.createTempDirectory("arthas-mcp-uploads-") throws IOException. This method runs inside a static initializer (DefaultUploadRootHolder class at line 447-449), so a failure here causes an ExceptionInInitializerError at class-load time, preventing UploadFileTool from being used at all.

Source

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

                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 权限。
        }
    }

    private static void setFilePermissions(Path file) throws IOException {
        try {
            Files.setPosixFilePermissions(file, FILE_PERMISSIONS);
        } catch (UnsupportedOperationException ignored) {
            // 当前文件系统不支持 POSIX 权限。
        }
    }

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Ensure java.io.tmpdir is writable and has free space and inodes.
  2. Start the JVM with -Djava.io.tmpdir=/path/to/writable/dir to redirect temp files.
  3. Clean up disk space or old temp files in the current tmpdir.
  4. Fix filesystem mount options (read-write) for the temp directory.

Example fix

// before: JVM started with default tmpdir that is full or read-only
java -jar arthas-boot.jar
// after: redirect tmpdir to a writable location with space
java -Djava.io.tmpdir=/data/tmp -jar arthas-boot.jar
Defensive patterns

Strategy: try-catch

Validate before calling

// Before class-load, verify java.io.tmpdir is writable
Path tmp = Paths.get(System.getProperty("java.io.tmpdir"));
Path testFile = tmp.resolve("arthas-mcp-upload-probe-" + System.nanoTime());
try {
    Files.createDirectories(tmp);
    Files.createFile(testFile);
    Files.delete(testFile);
} catch (IOException e) {
    throw new IllegalStateException(
        "Temp directory is not writable: " + tmp + " — set -Djava.io.tmpdir", e);
}

Try / catch

// This fires in a static initializer; catch at the JVM level is limited.
// Prevent it by validating tmpdir before the class loads:
try {
    Class.forName("com.taobao.arthas.core.mcp.tool.function.basic1000.UploadFileTool");
} catch (ExceptionInInitializerError e) {
    if (e.getCause() instanceof IllegalStateException
            && e.getCause().getMessage().contains("Failed to create MCP upload directory")) {
        // tmpdir is full or read-only — restart with -Djava.io.tmpdir=/writable/dir
    }
}

Prevention

When it happens

Trigger: The JVM's temp directory (java.io.tmpdir, typically /tmp) is full, read-only, or inaccessible when the UploadFileTool class is first loaded and the static initializer runs.

Common situations: Disk full in /tmp; container has a read-only tmpfs at /tmp; tmpdir permissions changed after JVM start; no space left on device; /tmp mounted noexec or with insufficient inode quota.

Related errors


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