apache/hadoop · error · PathIsNotEmptyDirectoryException
{path}
Error message
{path} What it means
In the POSIX delete path, a directory is checked for contents with isFolderEmpty; delete(f, recursive=false) on a non-empty directory throws PathIsNotEmptyDirectoryException with the path string as the message. The bucket root (empty key) is refused separately, and an empty folder is deleted as a single object.
Source
Thrown at hadoop-cloud-storage-project/hadoop-huaweicloud/src/main/java/org/apache/hadoop/fs/obs/OBSPosixBucketUtils.java:353
Path f = status.getPath();
String key = OBSCommonUtils.pathToKey(owner, f);
if (!status.isDirectory()) {
LOG.debug("delete: Path is a file");
trashObjectIfNeed(owner, key);
} else {
LOG.debug("delete: Path is a directory: {} - recursive {}", f,
recursive);
key = OBSCommonUtils.maybeAddTrailingSlash(key);
boolean isEmptyDir = OBSCommonUtils.isFolderEmpty(owner, key);
if (key.equals("")) {
return OBSCommonUtils.rejectRootDirectoryDelete(
owner.getBucket(), isEmptyDir, recursive);
}
if (!recursive && !isEmptyDir) {
LOG.warn("delete: Path is not empty: {} - recursive {}", f,
recursive);
throw new PathIsNotEmptyDirectoryException(f.toString());
}
if (isEmptyDir) {
LOG.debug(
"delete: Deleting fake empty directory {} - recursive {}",
f, recursive);
OBSCommonUtils.deleteObject(owner, key);
} else {
LOG.debug(
"delete: Deleting objects for directory prefix {} to "
+ "delete - recursive {}", f, recursive);
trashFolderIfNeed(owner, key, f);
}
}
long endTime = System.currentTimeMillis();
LOG.debug("delete Path:{} thread:{}, timeUsedInMilliSec:{}", f,
threadId, endTime - startTime);
return true;View on GitHub (pinned to 2add963021)
Solutions
- Pass recursive=true when the whole tree must go: fs.delete(dir, true)
- List and selectively delete children when only part of the content should be removed
- Re-check directory contents on failure when a concurrent-writer race is plausible
Example fix
// before fs.delete(dir, false); // after fs.delete(dir, true);
Defensive patterns
Strategy: validation
Validate before calling
if (fs.getFileStatus(dir).isDirectory() && fs.listStatus(dir).length > 0
&& !recursive) {
throw new PathIsNotEmptyDirectoryException(dir.toString());
} Type guard
static boolean isEmptyDirectory(FileSystem fs, Path p) throws IOException {
return fs.getFileStatus(p).isDirectory() && fs.listStatus(p).length == 0;
} Try / catch
try {
fs.delete(dir, false);
} catch (PathIsNotEmptyDirectoryException e) {
// content arrived concurrently: re-list and choose delete(dir, true) or skip
} Prevention
- Pass recursive=true for full tree removal
- Use explicit child listing for partial cleanup
- Schedule deletes outside window where writers may still add content
When it happens
Trigger: fs.delete(dir, false) while dir contains objects or subfolders; cleanup routines that assumed non-recursive delete on object storage removes everything; partition drops without the recursive flag.
Common situations: Code ported from HDFS or local filesystems; concurrent writers adding content between the emptiness check and the delete; scheduled cleanup jobs configured non-recursive by default.
Related errors
- {path}
- Can not delete the directory: [%s], as it is not empty and o
- {} is not a directory
- No such file or directory: {}
- File conflicts during rename, {}
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/7fefef6bbef82fa4.
Report an issue: GitHub.