Java permission denied, explained and fixed

When Java code opens a file it is not allowed to touch, the exception is often disguised: java.io.FileNotFoundException: /path/to/file (Permission denied) reads as if the file were missing, while the parenthetical gives the real reason. The JVM runs as some operating-system user, and that user lacks read or write permission on the file, write permission on the directory (for creating or renaming files), or execute (search) permission on a directory along the path. The code is usually fine; the identity the process runs as, and the file's ownership, disagree.

The checks, in order

  1. Identify the process user: the account the service, container, or terminal session runs Java as (whoami in the same context, the service definition, or System.getProperty("user.name") logged by the app). Every permission question is about this user, not the developer's login.
  2. Inspect the file and every directory above it: on Linux, ls -l the file and namei -l /full/path to see permissions along the whole chain; a single directory without execute permission for this user blocks everything beneath it. On Windows, check the file's Security tab and whether the folder is protected (system folders, another user's profile).
  3. Distinguish read from write problems: reading needs read on the file; creating a file needs write on the directory; appending needs write on the file; atomic save patterns (write temp, then rename) need write on the directory even when the file itself is writable.
  4. Check for non-permission impostors: a directory passed where a file is expected gives “Is a directory”, a file locked by another process on Windows gives “Access is denied” style errors, and SELinux or AppArmor can deny a permitted-looking file; the system log (audit.log, dmesg) records those denials.

The fixes

  1. Grant the specific access to the specific user: adjust ownership (chown) or add the minimal permission (chmod) on the file or directory involved; prefer ownership by the service account for application data directories.
  2. Move the data to where the process is expected to write: applications should not write beside the jar in protected install locations; use a designated data directory, the user's working directory, or a configured path.
  3. In containers, align the image's user with the mounted volume's ownership, or fix ownership at startup; a volume mounted from the host commonly arrives owned by a user the container process is not.
  4. Avoid the tempting non-fixes: running the whole application as root or administrator, or chmod 777, removes the error by removing the protection; both leave the system exposed and hide the real configuration mistake.

Common questions

Why does it say FileNotFoundException when the file exists? FileInputStream and FileOutputStream historically report open failures through FileNotFoundException, appending the operating system's reason in parentheses. “(Permission denied)” in that message means the file was found and refused, not missing.

It works when I run it, but fails as a service, why? Different users. Your shell runs as you; the service runs as its service account (often with minimal rights), and the file is owned by you. The service user's permissions are the ones that matter.

The permissions look right but it still fails, what else? Check the directories above the file (a common blind spot), Windows file locks by another process, and on Linux the security modules (SELinux/AppArmor) whose denials appear in system logs rather than in ls output.

Related errors

Permission denied (Linux) · NoClassDefFoundError · Could not find or load main class