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
- Inspect the offending ancestor path (third `%s` in the message) and remove or relocate the file blocking the chain.
- Rerun `./gradlew clean` to reset the build tree if the conflict is a stale artifact.
- Adjust one of the paths so file and directory trees don't overlap.
- 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
- Keep output-path trees disjoint: never reuse a file path as a directory prefix.
- Audit generated-file locations before introducing new directory conventions.
- Check for mid-path symlinks with `ls -la` / `readlink -f` when debugging.
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
- Unable to create reaper JAR output directory {}
- Cannot create directory '%s' as it already exists, but is no
- Failed to create parent directory '%s' when creating directo
- Failed to create directory '%s'
- Failed to patch archive
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/a055ec23ac55bfb8.
Report an issue: GitHub.