juicedata/juicefs · warning · AccessControlException

Permission denied: user=" + user + ", access=" + action + ",

Error message

Permission denied: user=" + user + ", access=" + action + ", path=\"" + path + "\"

What it means

RangerPermissionChecker.checkPermission throws AccessControlException when the path's owner does not match the requesting user and owner-only access (checkOwner) is required. The message is built by assembleExceptionMessage with user, action and path.

Source

Thrown at sdk/java/src/main/java/io/juicefs/permission/RangerPermissionChecker.java:165

      if (checkResult(authzStatus, user, parentAccess.toString(), toPathString(obj.parent.getPath()))) {
        return fallback;
      }
    }

    if (authzStatus == AuthzStatus.ALLOW && access != null && obj.current != null) {
      authzStatus = isAccessAllowed(obj.current, access, context);
      if (checkResult(authzStatus, user, access.toString(), toPathString(obj.current.getPath()))) {
        return fallback;
      }
    }

    if (checkOwner) {
      String owner = null;
      if (obj.current != null) {
        owner = obj.current.getOwner();
      }
      if (!user.equals(owner)) {
        throw new AccessControlException(
            assembleExceptionMessage(user, getFirstNonNullAccess(ancestorAccess, parentAccess, access),
                toPathString(obj.current.getPath())));
      }
    }
    // check access by ranger success
    return !fallback;
  }

  public void cleanUp() {
    try {
      rangerPlugin.cleanup();
    } catch (Exception e) {
      LOG.warn("Error when clean up ranger plugin threads.", e);
    }
    try {
      superGroupFileSystem.close();
    } catch (Exception e) {
      LOG.warn("Error when close super group file system.", e);

View on GitHub (pinned to c9a67b23e8)

Solutions

  1. Grant the user the required access via a Ranger policy
  2. Change file ownership (chown) if appropriate
  3. Access the path as the owning user
  4. Verify the path resolution picks the intended obj.current inode

Example fix

// before
hadoop fs -ls /jfs/vol/other-user-dir  # as user 'alice'
// after (as owner or with granted policy)
sudo -u owner hadoop fs -ls /jfs/vol/other-user-dir
Defensive patterns

Strategy: try-catch

Validate before calling

FileStatus st = fs.getFileStatus(path);
String owner = st.getOwner();
boolean ownerRestricted = !currentUser.equals(owner); // requires owner-access path

Type guard

boolean isOwner(FileStatus st, String user) { return user.equals(st.getOwner()); }

Try / catch

try {
  checker.checkPermission(user, action, path);
} catch (AccessControlException e) {
  LOG.warn("Access denied for " + user + " on " + path + ": " + e.getMessage());
  // surface a permission error to caller or fall back
}

Prevention

When it happens

Trigger: An ACL/ranger authorization path requiring owner check (e.g. sticky-bit or owner-scoped entry) where obj.current.getOwner() != user and no ancestor/parent access satisfies the requirement.

Common situations: User operating on files owned by another account without sufficient ranger policy; running jobs as a different user than file owner; missing ranger policies granting the user the needed access.

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 juicedata/juicefs@c9a67b23e8 (2026-09-06). Data as JSON: /api/errors/fd20018a2962559a. Report an issue: GitHub.