apache/hadoop · error · AccessControlException

Cannot delete/rename subdirectory under protected subdirecto

Error message

Cannot delete/rename subdirectory under protected subdirectory {}

What it means

When dfs.protected.subdirectories.enable=true (DFSConfigKeys.DFS_PROTECTED_SUBDIRECTORIES_ENABLE), DFSUtil.checkProtectedDescendants additionally walks upward from the target path, stripping one component at a time, and refuses the delete/rename if ANY ancestor is a protected directory. This protects everything below a protected path, not just the protected directory itself.

Source

Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/DFSUtil.java:1920

    // {@link Path#SEPARATOR} is "/" and '0' is the next ASCII
    // character after '/'.
    for (String descendant :
        protectedDirs.subSet(src + Path.SEPARATOR, src + "0")) {
      INodesInPath subdirIIP =
          fsd.getINodesInPath(descendant, FSDirectory.DirOp.WRITE);
      if (fsd.isNonEmptyDirectory(subdirIIP)) {
        throw new AccessControlException(
            "Cannot delete/rename non-empty protected subdirectory "
            + descendant);
      }
    }

    if (fsd.isProtectedSubDirectoriesEnable()) {
      while (!src.isEmpty()) {
        int index = src.lastIndexOf(Path.SEPARATOR_CHAR);
        src = src.substring(0, index);
        if (protectedDirs.contains(src)) {
          throw new AccessControlException(
              "Cannot delete/rename subdirectory under protected subdirectory "
              + src);
        }
      }
    }
  }

  /**
   * Generates HdfsFileStatus flags.
   * @param isEncrypted Sets HAS_CRYPT
   * @param isErasureCoded Sets HAS_EC
   * @param isSnapShottable Sets SNAPSHOT_ENABLED
   * @param hasAcl Sets HAS_ACL
   * @return HdfsFileStatus Flags
   */
  public static EnumSet<HdfsFileStatus.Flags> getFlags(
      final boolean isEncrypted, final boolean isErasureCoded,
      boolean isSnapShottable, boolean hasAcl) {

View on GitHub (pinned to 2add963021)

Solutions

  1. Move workloads/data out of the protected subtree and stop deleting beneath it
  2. Ask the admin to trim the ancestor from fs.protected.directories or set dfs.protected.subdirectories.enable=false, then restart/reload the NameNode
  3. Restructure so scratch data no longer lives below protected directories

Example fix

// before (hdfs-site.xml on NameNode)
<property><name>fs.protected.directories</name><value>/data</value></property>
<property><name>dfs.protected.subdirectories.enable</name><value>true</value></property>
// after (policy decision by admin: no subtree-wide protection)
<property><name>dfs.protected.subdirectories.enable</name><value>false</value></property>
Defensive patterns

Strategy: try-catch

Try / catch

try {
  fs.delete(deepPath, false);
} catch (AccessControlException e) {
  if (e.getMessage() != null && e.getMessage().contains("under protected subdirectory")) {
    // an ancestor of deepPath is protected with dfs.protected.subdirectories.enable=true:
    // relocate the data instead of deleting beneath the protected root
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: NameNode configured with dfs.protected.subdirectories.enable=true plus fs.protected.directories containing an ancestor; any delete or rename under that subtree (even of a single deep file) throws AccessControlException naming the protected ancestor.

Common situations: Admins tighten protection of whole subtrees; existing cleanup jobs that delete files below the protected directory start failing; the flag being enabled only on some NameNodes causing inconsistent behavior.

Related errors


AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22). Data as JSON: /api/errors/16f20b1d55988734. Report an issue: GitHub.