eclipse-vertx/vert.x · error · FileSystemException

Accessed denied for chmod on ${path}

Error message

Accessed denied for chmod on ${path}

What it means

The chmod action catches SecurityException from java.nio.file.Files.setPosixFilePermissions (or the ACP variant) and throws FileSystemException 'Accessed denied for chmod on <path>'. A SecurityException here signals the JVM or OS refused the permission change. Unlike the IOException branch, no cause is attached; the message names only the path.

Source

Thrown at vertx-core/src/main/java/io/vertx/core/file/impl/FileSystemImpl.java:547

          if (dirPermissions != null) {
            Files.walkFileTree(target, new SimpleFileVisitor<Path>() {
              public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException {
                //The directory entries typically have different permissions to the files, e.g. execute permission
                //or can't cd into it
                Files.setPosixFilePermissions(dir, dirPermissions);
                return FileVisitResult.CONTINUE;
              }

              public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
                Files.setPosixFilePermissions(file, permissions);
                return FileVisitResult.CONTINUE;
              }
            });
          } else {
            Files.setPosixFilePermissions(target, permissions);
          }
        } catch (SecurityException e) {
          throw new FileSystemException("Accessed denied for chmod on " + path);
        } catch (IOException e) {
          throw new FileSystemException(getFileAccessErrorMessage("chmod", path), e);
        }
        return null;
      }
    };
  }

  protected BlockingAction<Void> chownInternal(String path, String user, String group) {
    Objects.requireNonNull(path);
    return new BlockingAction<Void>() {
      public Void perform() {
        try {
          Path target = resolveFile(path).toPath();
          UserPrincipalLookupService service = target.getFileSystem().getUserPrincipalLookupService();
          UserPrincipal userPrincipal = user == null ? null : service.lookupPrincipalByName(user);
          GroupPrincipal groupPrincipal = group == null ? null : service.lookupPrincipalByGroupName(group);
          if (groupPrincipal != null) {

View on GitHub (pinned to fb308bd8c3)

Solutions

  1. Run the Vert.x process as the owner of the file, or change ownership beforehand (chown) so the app user can chmod it.
  2. Fix the Docker/user mismatch: run the container with the UID owning the mounted volume, or pre-set permissions on the host.
  3. If a SecurityManager is active, grant FilePermission/SecurityPermission for the path in the policy file.
  4. On non-POSIX filesystems, apply permissions out-of-band (icacls on Windows, mount options) instead of fs.chmod.

Example fix

// before
vertx.fileSystem().chmodBlocking("/var/log/app/app.log", "rw-r--r--"); // owned by other user
// after: align ownership first (host/entrypoint), then chmod as app user
// entrypoint.sh: chown -R app:app /var/log/app || true
vertx.fileSystem().chmodBlocking("/var/log/app/app.log", "rw-r--r--");
Defensive patterns

Strategy: try-catch

Validate before calling

Path p = Paths.get(path);
if (!Files.exists(p)) throw new FileNotFoundException(path);
try {
  Files.getPosixFilePermissions(p);
} catch (UnsupportedOperationException e) {
  throw new IllegalStateException("Filesystem lacks POSIX permissions: " + p);
}
if (!p.toFile().canWrite() || !isOwner(p))
  throw new AccessDeniedException("not owner of " + p);

Type guard

static boolean canChmod(Path p) {
  try {
    return Files.getOwner(p).equals(Files.getFileSystem().getUserPrincipalLookupService()
        .lookupPrincipalByName(System.getProperty("user.name")));
  } catch (IOException | UnsupportedOperationException e) { return false; }
}

Try / catch

try {
  fs.chmodBlocking(path, "rw-r--r--");
} catch (FileSystemException e) {
  if (e.getMessage().startsWith("Accessed denied for chmod")) {
    // fix ownership out-of-band: chown on host / match container UID
  } else throw e;
}

Prevention

When it happens

Trigger: vertx.fileSystem().chmod(path, perms) on a file not owned by the current user, on a filesystem without POSIX permission support being forced down the POSIX path, or under a Java SecurityManager policy denying the operation.

Common situations: chmod'ing files created by a different service user in a shared directory; running the app as non-root and chmod'ing system paths; Docker containers where the app user differs from the volume file owner; SELinux confinement; Windows filesystems where POSIX semantics are emulated.

Understand the failure class

Background: Permission denied / not authorized / 403 Forbidden: access-control rejections when the caller lacks the required role, grant, or ownership — this error's family across 18 libraries.

Related errors


AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06). Data as JSON: /api/errors/e9b6d9ff95fb5588. Report an issue: GitHub.