apache/hadoop · error · IOException
Destination '{parentFile}' directory cannot be created
Error message
Destination '{parentFile}' directory cannot be created What it means
Guard clause of Storage.nativeCopyFileUnbuffered: destFile.getParentFile() could neither be created (mkdirs() false) nor already existed as a directory, so the copy aborts before writing. This means the destination parent path is unusable - shadowed by a regular file, unwritable, or on a read-only mount.
Source
Thrown at hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/common/Storage.java:1345
throw new NullPointerException("Source must not be null");
}
if (destFile == null) {
throw new NullPointerException("Destination must not be null");
}
if (srcFile.exists() == false) {
throw new FileNotFoundException("Source '" + srcFile + "' does not exist");
}
if (srcFile.isDirectory()) {
throw new IOException("Source '" + srcFile + "' exists but is a directory");
}
if (srcFile.getCanonicalPath().equals(destFile.getCanonicalPath())) {
throw new IOException("Source '" + srcFile + "' and destination '" +
destFile + "' are the same");
}
File parentFile = destFile.getParentFile();
if (parentFile != null) {
if (!parentFile.mkdirs() && !parentFile.isDirectory()) {
throw new IOException("Destination '" + parentFile
+ "' directory cannot be created");
}
}
if (destFile.exists()) {
if (FileUtil.canWrite(destFile) == false) {
throw new IOException("Destination '" + destFile
+ "' exists but is read-only");
} else {
if (destFile.delete() == false) {
throw new IOException("Destination '" + destFile
+ "' exists but cannot be deleted");
}
}
}
try {
NativeIO.copyFileUnbuffered(srcFile, destFile);
} catch (NativeIOException e) {
throw new IOException("Failed to copy " + srcFile.getCanonicalPath()View on GitHub (pinned to 2add963021)
Solutions
- Check whether a regular file shadows the parent path: ls -l <parent> and remove or relocate it
- Create the directory yourself as the daemon user, or chown/chmod it so mkdirs can succeed
- Confirm the volume is mounted read-write
Example fix
// before
Storage.nativeCopyFileUnbuffered(src, new File("/data/x/y/fsimage"), true); // /data/x is a file
// after
Files.createDirectories(new File("/data/x/y").toPath());
Storage.nativeCopyFileUnbuffered(src, new File("/data/x/y/fsimage"), true); Defensive patterns
Strategy: validation
Validate before calling
File parent = destFile.getParentFile();
if (parent != null) {
if (parent.exists() && !parent.isDirectory())
throw new IOException("path shadowed by a file: " + parent);
Files.createDirectories(parent.toPath());
} Prevention
- Pre-create destination directories as part of setup instead of relying on the library's mkdirs
- Alert when mkdirs fails - it almost always means a permissions or shadowing problem
- Keep storage-dir ownership consistent with the daemon user
When it happens
Trigger: A regular file occupies a path component of the destination directory (e.g. /data/x is a file, dest is /data/x/y); the daemon user lacks write permission on the grandparent; the volume is mounted read-only; NFS export denies directory creation.
Common situations: Manually created placeholder files where directories were expected; storage dirs prepared by root with wrong ownership; read-only recovery mounts; container images with conflicting paths.
Related errors
- Destination '{destFile}' exists but is read-only
- Mkdirs failed to create {} (exists={}, cwd={})
- Permission denied: user=%s, path="%s":%s:%s:%s%s
- {} doesn't support modifyAclEntries
- {} doesn't support removeAclEntries
AI-assisted analysis of apache/hadoop@2add963021 (2026-08-22).
Data as JSON: /api/errors/4de84387c6082298.
Report an issue: GitHub.