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
- Move workloads/data out of the protected subtree and stop deleting beneath it
- Ask the admin to trim the ancestor from fs.protected.directories or set dfs.protected.subdirectories.enable=false, then restart/reload the NameNode
- 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
- Know whether dfs.protected.subdirectories.enable is on before scheduling deletes under protected roots
- Keep scratch/temp data out of protected subtrees so subtree protection never surprises cleanup jobs
- Admins: communicate that enabling the flag protects ALL descendants, not just the listed directory
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
- Cannot delete/rename non-empty protected directory {}
- Cannot delete/rename non-empty protected subdirectory {}
- Destination '{destFile}' exists but cannot be deleted
- Failed to delete {dir}
- Directory {dir} is in an inconsistent state: storage directo
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/16f20b1d55988734.
Report an issue: GitHub.