{"record":{"id":"ef38190848decc9c","repo":"alibaba/arthas","slug":"file-cannot-be-written-to","errorCode":null,"errorMessage":"File '{}' cannot be written to","messagePattern":"File '(.+?)' cannot be written to","errorType":"exception","errorClass":"IOException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/com/taobao/arthas/core/util/FileUtils.java","lineNumber":80,"sourceCode":"     * An exception is thrown if the file exists but cannot be written to.\n     * An exception is thrown if the parent directory cannot be created.\n     *\n     * @param file  the file to open for output, must not be {@code null}\n     * @param append if {@code true}, then bytes will be added to the\n     * end of the file rather than overwriting\n     * @return a new {@link FileOutputStream} for the specified file\n     * @throws IOException if the file object is a directory\n     * @throws IOException if the file cannot be written to\n     * @throws IOException if a parent directory needs creating but that fails\n     * @since 2.1\n     */\n    public static FileOutputStream openOutputStream(File file, boolean append) throws IOException {\n        if (file.exists()) {\n            if (file.isDirectory()) {\n                throw new IOException(\"File '\" + file + \"' exists but is a directory\");\n            }\n            if (!file.canWrite()) {\n                throw new IOException(\"File '\" + file + \"' cannot be written to\");\n            }\n        } else {\n            File parent = file.getParentFile();\n            if (parent != null) {\n                if (!parent.mkdirs() && !parent.isDirectory()) {\n                    throw new IOException(\"Directory '\" + parent + \"' could not be created\");\n                }\n            }\n        }\n        return new FileOutputStream(file, append);\n    }\n\n    private static boolean isAuthCommand(String command) {\n        // 需要改写 auth command, TODO 更准确应该是用mask去掉密码信息\n        return command != null && command.trim().startsWith(ArthasConstants.AUTH);\n    }\n\n    /**","sourceCodeStart":62,"sourceCodeEnd":98,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/core/src/main/java/com/taobao/arthas/core/util/FileUtils.java#L62-L98","documentation":"FileUtils.openOutputStream() throws this IOException when the target File exists and is a regular file but is not writable by the current process. This is a permission/ownership check before attempting to construct the FileOutputStream.","triggerScenarios":"Calling openOutputStream(file, append) where file.exists() is true, file.isDirectory() is false, but file.canWrite() returns false.","commonSituations":"The output file is owned by another user and lacks world/group write permission; the file is on a read-only filesystem; the JVM process runs as a different user than the file owner; a previous run created the file as root and the current run is non-root.","solutions":["Check and fix file permissions: chmod u+w <file> or chown to the JVM user.","If running in a container, ensure the mounted volume is writable by the container user.","Redirect output to a writable directory/file (e.g. under /tmp or a designated writable path).","Remove the stale read-only file so openOutputStream can recreate it."],"exampleFix":"// before: file owned by root, JVM runs as appuser\nFile out = new File(\"/var/log/arthas.log\");\nFileUtils.openOutputStream(out, true); // throws 'cannot be written to'\n\n// after: use a writable location\nFile out = new File(System.getProperty(\"java.io.tmpdir\"), \"arthas.log\");\nFileUtils.openOutputStream(out, true);","handlingStrategy":"validation","validationCode":"File file = new File(outputPath);\nif (file.exists() && !file.canWrite()) {\n    throw new IllegalStateException(\"File not writable: \" + file + \" — check permissions\");\n}\nFileUtils.openOutputStream(file, append);","typeGuard":null,"tryCatchPattern":"try {\n    FileUtils.openOutputStream(file, append);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"cannot be written\")) {\n        file = new File(System.getProperty(\"java.io.tmpdir\"), \"arthas-output.log\");\n        FileUtils.openOutputStream(file, append);\n    } else { throw e; }\n}","preventionTips":["Ensure the JVM process user owns or has write access to the output file.","In containers, verify volume mount permissions before writing."],"tags":["arthas","file-io","permissions","filesystem"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}