{"record":{"id":"13e98f8f5cb2b351","repo":"java-native-access/jna","slug":"jna-temporary-directory-jnatmp-is-not-writable","errorCode":null,"errorMessage":"JNA temporary directory 'jnatmp' is not writable","messagePattern":"JNA temporary directory 'jnatmp' is not writable","errorType":"exception","errorClass":"java.io.IOException","httpStatus":null,"severity":"critical","filePath":"src/com/sun/jna/Native.java","lineNumber":1425,"sourceCode":"                }\n                jnatmp = new File(xdgCacheFile, \"JNA/temp\");\n            } else {\n                // Loading DLLs via System.load() under a directory with a unicode\n                // name will fail on windows, so use a hash code of the user's\n                // name in case the user's name contains non-ASCII characters\n                jnatmp = new File(tmp, \"jna-\" + System.getProperty(\"user.name\").hashCode());\n            }\n\n            jnatmp.mkdirs();\n            if (!jnatmp.exists() || !jnatmp.canWrite()) {\n                jnatmp = tmp;\n            }\n        }\n        if (!jnatmp.exists()) {\n            throw new IOException(\"JNA temporary directory '\" + jnatmp + \"' does not exist\");\n        }\n        if (!jnatmp.canWrite()) {\n            throw new IOException(\"JNA temporary directory '\" + jnatmp + \"' is not writable\");\n        }\n        return jnatmp;\n    }\n\n    /** Remove all marked temporary files in the given directory. */\n    static void removeTemporaryFiles() throws IOException {\n        File dir = getTempDir();\n        FilenameFilter filter = new FilenameFilter() {\n            @Override\n            public boolean accept(File dir, String name) {\n                return name.endsWith(\".x\") && name.startsWith(JNA_TMPLIB_PREFIX);\n            }\n        };\n        File[] files = dir.listFiles(filter);\n        for (int i=0;files != null && i < files.length;i++) {\n            File marker = files[i];\n            String name = marker.getName();\n            name = name.substring(0, name.length()-2);","sourceCodeStart":1407,"sourceCodeEnd":1443,"githubUrl":"https://github.com/java-native-access/jna/blob/d036ad9781adad4b66693e8fa7098e4ac665e0a3/src/com/sun/jna/Native.java#L1407-L1443","documentation":"JNA stages its native library into a temporary directory and requires write access there to extract the .so/.dll/.jnilib file. After confirming the directory exists, it checks canWrite(); if the process lacks write permission it throws this IOException. Without write access JNA cannot materialize the native library, so native calls cannot proceed.","triggerScenarios":"First JNA library load when the resolved temp directory (jna.tmpdir or jnatmp* under java.io.tmpdir) exists but is not writable by the JVM's OS user.","commonSituations":"Running a JVM as a non-root user while the temp dir is root-owned, hardened containers with read-only volumes, or a shared jna.tmpdir created earlier by another user with restrictive permissions.","solutions":["chown/chmod the temp directory so the JVM user can write to it (e.g. chmod 1777 like /tmp).","Point JNA at a writable directory with -Djna.tmpdir=/path/writable (or JNA_TMPDIR env var).","Run the process under a user that owns or can write to java.io.tmpdir.","Prefer bundling the native library on java.library.path or use OSGi-native bundling so JNA does not need to extract to a temp dir."],"exampleFix":"// before\nls -ld /opt/jnatmp  # drwxr-xr-x root root; app runs as 'appuser' -> not writable\n\n// after\nsudo chown appuser /opt/jnatmp\njava -Djna.tmpdir=/opt/jnatmp -jar app.jar","handlingStrategy":"validation","validationCode":"File dir = new File(System.getProperty(\"jna.tmpdir\",\n    System.getProperty(\"java.io.tmpdir\")));\nif (dir.isDirectory() && !dir.canWrite()) {\n    throw new IllegalStateException(\"jna.tmpdir must be writable by user \" + System.getProperty(\"user.name\"));\n}","typeGuard":null,"tryCatchPattern":"try {\n    MyLib lib = Native.load(\"mylib\", MyLib.class);\n} catch (IOException e) {\n    if (e.getMessage().contains(\"is not writable\")) {\n        System.setProperty(\"jna.tmpdir\", \"/var/tmp/jna\");\n        // retry load\n    } else { throw e; }\n}","preventionTips":["Run the JVM under a user that owns or can write to the temp dir; mirror /tmp permissions (1777).","Mount a writable volume and point -Djna.tmpdir at it in hardened containers.","Check canWrite() on the configured dir during application startup, before first native call.","Avoid shared temp dirs created by other users with restrictive umasks."],"tags":["jna","temp-directory","permissions","io"],"backgroundTag":"file-write-permission-denied","analyzedSha":"d036ad9781adad4b66693e8fa7098e4ac665e0a3","analyzedAt":"2026-09-12T06:50:59.239Z","contentChangedAt":"2026-09-12T06:50:59.239Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}