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
- Delete or move the directory's contents first; an empty protected directory may then be removed, which is the intended escape hatch
- Operate on different paths outside the protected set
- 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
- Keep the current fs.protected.directories list visible to jobs (document it) so pipelines avoid protected roots
- Design cleanup jobs to delete contents first and tolerate the empty-dir-only rule
- Admins: normalize paths and test the protected set with a scratch directory before protecting production paths
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
- Cannot delete/rename non-empty protected subdirectory {}
- Cannot delete/rename subdirectory under protected subdirecto
- 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/c83c1051cfeccc87.
Report an issue: GitHub.