apache/hadoop · error · AccessControlException

Cannot delete/rename non-empty protected directory {}

Error message

Cannot delete/rename non-empty protected directory {}

What it means

HDFS protected directories (fs.protected.directories, CommonConfigurationKeysPublic.java:153: 'Directories that cannot be removed unless empty, even by an administrator') are enforced by DFSUtil.checkProtectedDescendants, called on every delete (FSDirDeleteOp.java:114) and rename (FSDirRenameOp.java:287,509). If the path being deleted/renamed is itself in the protected set and non-empty, AccessControlException is thrown.

Source

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

   * @param iip directory whose descendants are to be checked.
   * @throws AccessControlException if a non-empty protected descendant
   *                                was found.
   * @throws ParentNotDirectoryException
   * @throws UnresolvedLinkException
   */
  public static void checkProtectedDescendants(
      FSDirectory fsd, INodesInPath iip)
          throws AccessControlException, UnresolvedLinkException,
          ParentNotDirectoryException {
    final SortedSet<String> protectedDirs = fsd.getProtectedDirectories();
    if (protectedDirs.isEmpty()) {
      return;
    }

    String src = iip.getPath();
    // Is src protected? Caller has already checked it is non-empty.
    if (protectedDirs.contains(src)) {
      throw new AccessControlException(
          "Cannot delete/rename non-empty protected directory " + src);
    }

    // Are any descendants of src protected?
    // The subSet call returns only the descendants of src since
    // {@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);
      }
    }

View on GitHub (pinned to 2add963021)

Solutions

  1. Delete or move the directory's contents first; an empty protected directory may then be removed, which is the intended escape hatch
  2. Operate on different paths outside the protected set
  3. If removal is genuinely intended, have the HDFS admin remove the path from fs.protected.directories in the NameNode config and restart/reload before retrying

Example fix

// before
hdfs dfs -rm -r /warehouse          // protected and non-empty -> AccessControlException
// after
hdfs dfs -rm /warehouse/*           // empty it first
hdfs dfs -rm /warehouse             // empty protected dir is now allowed
Defensive patterns

Strategy: try-catch

Try / catch

try {
  fs.delete(path, true);
} catch (AccessControlException e) {
  if (e.getMessage() != null && e.getMessage().contains("protected")) {
    // path is policy-protected and non-empty: skip, do not escalate
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: hdfs dfs -rm -r (or rename) targeting a directory that is listed in fs.protected.directories on the NameNode and still contains children.

Common situations: Admins protect data zones such as /warehouse or /user/archive; batch jobs or users then attempt recursive deletes/reorganizations of those paths and are refused even with superuser rights.

Related errors


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