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

  1. Pre-create the temp directory and make it writable: mkdir -p $JNA_TMPDIR with proper permissions.
  2. Set -Djna.tmpdir=/some/writable/dir (or JNA_TMPDIR env var) to a directory that exists and is writable by the JVM user.
  3. Restore java.io.tmpdir to an existing writable location (or restart with -Djava.io.tmpdir=/writable/tmp).
  4. 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

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


AI-assisted analysis of java-native-access/jna@d036ad9781 (2026-09-12). Data as JSON: /api/errors/0cd0a8cc57006a43. Report an issue: GitHub.