elastic/elasticsearch · error · UncheckedIOException

Cannot create parent directory '%s' when creating directory

Error message

Cannot create parent directory '%s' when creating directory '%s' as '%s' is not a directory

What it means

FileUtils.mkdirs() throws while walking up parent dirs to create: for a parent that needs creating, it checks that the parent-of-that-parent `isDirectory()`. If a path component in the chain is a FILE (not a directory), you can't create a directory beneath it — the OS would refuse — so this fails fast with the three relevant paths named (the parent being created, the target dir, and the offending non-directory ancestor).

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/util/FileUtils.java:50

        if (dir.exists() && dir.isDirectory() == false) {
            throw new UncheckedIOException(String.format("Cannot create directory '%s' as it already exists, but is not a directory", dir));
        }

        List<File> toCreate = new LinkedList<File>();
        File parent = dir.getParentFile();
        while (parent.exists() == false) {
            toCreate.add(parent);
            parent = parent.getParentFile();
        }
        Collections.reverse(toCreate);
        for (File parentDirToCreate : toCreate) {
            if (parentDirToCreate.isDirectory()) {
                continue;
            }
            File parentDirToCreateParent = parentDirToCreate.getParentFile();
            if (parentDirToCreateParent.isDirectory() == false) {
                throw new UncheckedIOException(
                    String.format(
                        "Cannot create parent directory '%s' when creating directory '%s' as '%s' is not a directory",
                        parentDirToCreate,
                        dir,
                        parentDirToCreateParent
                    )
                );
            }
            if (parentDirToCreate.mkdir() == false && parentDirToCreate.isDirectory() == false) {
                throw new UncheckedIOException(
                    String.format("Failed to create parent directory '%s' when creating directory '%s'", parentDirToCreate, dir)
                );
            }
        }
        if (dir.mkdir() == false && dir.isDirectory() == false) {
            throw new UncheckedIOException(String.format("Failed to create directory '%s'", dir));
        }
    }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Inspect the offending ancestor path (third `%s` in the message) and remove or relocate the file blocking the chain.
  2. Rerun `./gradlew clean` to reset the build tree if the conflict is a stale artifact.
  3. Adjust one of the paths so file and directory trees don't overlap.
  4. On Unix, check for symlinks (`ls -la` / `readlink`) mid-path that resolve to files.

Example fix

# before: /a/b is a file, blocking /a/b/c
rm /a/b
# now mkdirs(/a/b/c) can proceed
Defensive patterns

Strategy: validation

Validate before calling

// Walk the path chain; reject if any existing component is a non-directory
File f = dir.getAbsoluteFile();
while (f != null) {
  if (f.exists() && !f.isDirectory()) {
    throw new IllegalStateException("Non-directory component blocks mkdirs: " + f);
  }
  f = f.getParentFile();
}

Prevention

When it happens

Trigger: Requesting `mkdirs(/a/b/c/d)` where some intermediate like `/a/b` is a regular file. The walk-up collects `/a/b/c` to create, then sees its parent `/a/b` is not a directory, triggering this guard.

Common situations: An earlier task wrote a file at `/a/b`, later a task tries to create `/a/b/c/d`; a symlink to a file in the middle of a path; misconfigured output paths that collide across plugins; a generated file (e.g. a `.jar`) whose path overlaps a desired directory tree.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/a055ec23ac55bfb8. Report an issue: GitHub.