apache/hadoop · error · AccessControlException

Permission denied: {} is not allowed to change quota of {}

Error message

Permission denied: {} is not allowed to change quota of {}

What it means

Quota.setQuota() throws AccessControlException when checkMountEntry is true and isMountEntry(path) confirms the path is itself a mount table entry. Quota for a mount point must be managed via the mount table (hdfs dsadmin commands / RouterAdmin updateMountTableEntry with quota), not via dfsadmin setQuota on the exact mount path, so the Router rejects the direct RPC.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/router/Quota.java:87

  }

  /**
   * Set quota for the federation path.
   * @param path Federation path.
   * @param namespaceQuota Name space quota.
   * @param storagespaceQuota Storage space quota.
   * @param type StorageType that the space quota is intended to be set on.
   * @param checkMountEntry whether to check the path is a mount entry.
   * @throws IOException If the quota system is disabled or if
   * checkMountEntry is true and the path is a mount entry.
   */
  public void setQuota(String path, long namespaceQuota, long storagespaceQuota,
      StorageType type, boolean checkMountEntry) throws IOException {
    if (!router.isQuotaEnabled()) {
      throw new IOException("The quota system is disabled in Router.");
    }
    if (checkMountEntry && isMountEntry(path)) {
      throw new AccessControlException(
          "Permission denied: " + RouterRpcServer.getRemoteUser()
              + " is not allowed to change quota of " + path);
    }
    setQuotaInternal(path, null, namespaceQuota, storagespaceQuota, type);
  }

  /**
   * Set quota for the federation path.
   * @param path Federation path.
   * @param locations Locations of the Federation path.
   * @param namespaceQuota Name space quota.
   * @param storagespaceQuota Storage space quota.
   * @param type StorageType that the space quota is intended to be set on.
   * @throws IOException If the quota system is disabled.
   */
  void setQuotaInternal(String path, List<RemoteLocation> locations,
      long namespaceQuota, long storagespaceQuota, StorageType type)
      throws IOException {

View on GitHub (pinned to 2add963021)

Solutions

  1. To set quota on a mount point, update the mount entry itself: hdfs dsadmin -updateMount <src> <ns> <dest> -nsquota <n> -ssquota <s> (RouterAdmin set/quota in mount table)
  2. To set quota on a normal subdirectory (not a mount entry), run dfsadmin -setQuota on a non-mount path under the mount
  3. Audit scripts to skip paths that appear in the mount table (hdfs dsadmin -listMountTable)

Example fix

# before: rejected, /data is a mount entry
hdfs dfsadmin -fs hdfs://router -setQuota 100000 /data

# after: set quota via the mount table entry
hdfs dsadmin -updateMount /data ns1 /data -nsquota 100000 -ssquota 1073741824
Defensive patterns

Strategy: validation

Validate before calling

// Skip paths that are themselves mount entries before calling setQuota(checkMountEntry=true)
MountTableResolver resolver = (MountTableResolver) router.getSubclusterResolver();
if (resolver.getMountPoint(path) != null) {
  throw new IllegalArgumentException(path + " is a mount entry; update its quota via the mount table");
}
quota.setQuota(path, nsQuota, ssQuota, type, true);

Try / catch

try {
  quota.setQuota(path, nq, sq, type, true);
} catch (AccessControlException e) {
  if (e.getMessage() != null && e.getMessage().contains("not allowed to change quota")) {
    // path is a mount entry: switch to mount-table quota update (hdfs dsadmin -updateMount ... -nsquota ...)
  } else { throw e; }
}

Prevention

When it happens

Trigger: hdfs dfsadmin -setQuota <mount-path> executed through the Router where <mount-path> exactly matches a mount table source path (checkMountEntry=true comes from the setQuota RPC path used by RouterClientProtocol.setQuota); scripted quota tooling that applies quotas to federation roots.

Common situations: Operators migrating from single-cluster HDFS run dfsadmin setQuota on the federation root; automation that sets quotas on every directory including mount points; confusion between mount-level quota (stored in the mount table record) and NS/DS quota on the underlying namespace.

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 apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/b0cbb7a7c0f6f2d2. Report an issue: GitHub.