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

  1. Check whether a regular file shadows the parent path: ls -l <parent> and remove or relocate it
  2. Create the directory yourself as the daemon user, or chown/chmod it so mkdirs can succeed
  3. 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

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


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