java-native-access/jna · critical · java.io.IOException
JNA temporary directory 'jnatmp' does not exist
Error message
JNA temporary directory 'jnatmp' does not exist
What it means
JNA extracts its bundled native library to a temporary directory ('jnatmp' under java.io.tmpdir by default, or jna.tmpdir). Before writing, it verifies the chosen directory exists; if mkdirs() failed and no usable fallback exists, it throws this IOException. This means JNA cannot even stage the native library file, so loading will fail.
Source
Thrown at src/com/sun/jna/Native.java:1422
xdgCacheFile = new File(System.getProperty("user.home"), ".cache");
} else {
xdgCacheFile = new File(xdgCacheEnvironment);
}
jnatmp = new File(xdgCacheFile, "JNA/temp");
} else {
// Loading DLLs via System.load() under a directory with a unicode
// name will fail on windows, so use a hash code of the user's
// name in case the user's name contains non-ASCII characters
jnatmp = new File(tmp, "jna-" + System.getProperty("user.name").hashCode());
}
jnatmp.mkdirs();
if (!jnatmp.exists() || !jnatmp.canWrite()) {
jnatmp = tmp;
}
}
if (!jnatmp.exists()) {
throw new IOException("JNA temporary directory '" + jnatmp + "' does not exist");
}
if (!jnatmp.canWrite()) {
throw new IOException("JNA temporary directory '" + jnatmp + "' is not writable");
}
return jnatmp;
}
/** Remove all marked temporary files in the given directory. */
static void removeTemporaryFiles() throws IOException {
File dir = getTempDir();
FilenameFilter filter = new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".x") && name.startsWith(JNA_TMPLIB_PREFIX);
}
};
File[] files = dir.listFiles(filter);
for (int i=0;files != null && i < files.length;i++) {View on GitHub (pinned to d036ad9781)
Solutions
- Pre-create the temp directory and make it writable: mkdir -p $JNA_TMPDIR with proper permissions.
- Set -Djna.tmpdir=/some/writable/dir (or JNA_TMPDIR env var) to a directory that exists and is writable by the JVM user.
- Restore java.io.tmpdir to an existing writable location (or restart with -Djava.io.tmpdir=/writable/tmp).
- Fix the environment: remount the filesystem read-write, free disk space, or adjust SecurityManager/policy rules blocking mkdirs.
Example fix
// before (read-only /tmp, no override) java -jar app.jar // JNA tries /tmp/jnatmp... -> IOException // after mkdir -p /var/tmp/jna && chmod 777 /var/tmp/jna java -Djna.tmpdir=/var/tmp/jna -jar app.jar
Defensive patterns
Strategy: validation
Validate before calling
File dir = new File(System.getProperty("jna.tmpdir",
System.getProperty("java.io.tmpdir")));
if (!dir.isDirectory() && !dir.mkdirs()) {
throw new IllegalStateException("Create a writable jna.tmpdir before loading JNA libraries");
} Try / catch
try {
MyLib lib = Native.load("mylib", MyLib.class);
} catch (IOException e) {
if (e.getMessage().contains("does not exist")) {
System.setProperty("jna.tmpdir", "/var/tmp/jna");
new File("/var/tmp/jna").mkdirs();
// retry load in a fresh classloader/restart
} else { throw e; }
} Prevention
- Provision and pre-create jna.tmpdir in container images and startup scripts.
- Set -Djna.tmpdir explicitly in read-only /tmp environments.
- Exclude JNA temp dirs from tmp cleaners (tmpwatch/systemd-tmpfiles).
- Smoke-test the first native load in CI with the same filesystem permissions as production.
When it happens
Trigger: Calling Native.load/loadLibrary (or any first JNA native call) when the configured temp directory (jna.tmpdir or jnatmp* under java.io.tmpdir) does not exist and could not be created — e.g. parent dir missing, read-only filesystem, or disk full.
Common situations: Containers/app servers with read-only /tmp, java.io.tmpdir pointing to a deleted or never-created path, security policies blocking file creation, or tmpwatch/systemd-tmpfiles cleaning the directory mid-run.
Related errors
- JNA temporary directory 'jnatmp' is not writable
- No trash location found (define fileutils.trash to be the pa
- errno: {eno}
- The following files could not be trashed: " + failed
- No support for " + os
AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12).
Data as JSON: /api/errors/0cd0a8cc57006a43.
Report an issue: GitHub.