elastic/elasticsearch · error · TestClustersException
Can not start {}, is not a directory: {}
Error message
Can not start {}, is not a directory: {} What it means
Thrown by ElasticsearchNode.start() after confirming the extracted distribution path exists but Files.isDirectory() returns false. The node refuses to boot because the extraction target is a regular file or a broken symlink rather than an unpacked ES home directory. It is a hard precondition guarding every downstream step that walks the distro tree (setupNodeDistribution, bin scripts, lib/modules).
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:475
distributions.forEach(ElasticsearchDistribution::maybeFreeze);
configurationFrozen.set(true);
}
private static String throwableToString(Throwable t) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
return sw.toString();
}
@Override
public synchronized void start() {
LOGGER.info("Starting `{}`", this);
if (Files.exists(getExtractedDistributionDir()) == false) {
throw new TestClustersException("Can not start " + this + ", missing: " + getExtractedDistributionDir());
}
if (Files.isDirectory(getExtractedDistributionDir()) == false) {
throw new TestClustersException("Can not start " + this + ", is not a directory: " + getExtractedDistributionDir());
}
try {
if (isWorkingDirConfigured == false) {
logToProcessStdout("Configuring working directory: " + workingDir);
// make sure we always start fresh
if (Files.exists(workingDir)) {
if (preserveDataDir) {
try (var files = Files.list(workingDir)) {
files.filter(path -> path.equals(confPathData) == false).forEach(this::uncheckedDeleteWithRetry);
}
} else {
deleteWithRetry(workingDir);
}
}
isWorkingDirConfigured = true;
}
setupNodeDistribution(getExtractedDistributionDir());View on GitHub (pinned to db6a809a66)
Solutions
- Delete the affected node's working/extracted directory (e.g. rm -rf build/testclusters/<node>) and rerun so the distribution is re-extracted.
- Check the distribution configuration: ensure the ElasticsearchDistribution type is one that unpacks to a directory (integ-test-zip or archive types that get extracted), not a raw file artifact.
- Verify the distribution download/extraction task ran successfully upstream; inspect the path printed in the message with ls -la to see whether it is a file or a dangling symlink.
- Run with --rerun-tasks or clean the testclusters task to force re-extraction.
Example fix
// before: distribution produces a single file, not an unpacked dir
testClusters {
myNode {
distribution 'elasticsearch', '8.0.0' // wrong type
}
}
// after: use the integ-test distribution which extracts to a directory
testClusters {
myNode {
distribution 'integ-test-zip', '8.0.0'
}
} Defensive patterns
Strategy: validation
Validate before calling
// Run before start() to confirm the extracted distro is a directory
Path distroDir = node.getExtractedDistributionDir();
if (!Files.isDirectory(distroDir)) {
throw new IllegalStateException("Extracted distro not a directory: " + distroDir
+ " (exists=" + Files.exists(distroDir) + "). Clean build/testclusters and rerun.");
} Prevention
- Do not delete parts of build/testclusters by hand; use the Gradle clean task so extraction state stays consistent.
- Pin the distribution type to integ-test-zip (or another directory-extracting type) in test cluster config.
- On CI, start from a clean workspace or use --rerun-tasks when distribution artifacts change.
When it happens
Trigger: Calling testClusters.start() (directly or via a TestClustersTask) when getExtractedDistributionDir() resolves to a file, a stale marker file, or a partially extracted archive whose top-level entry was not a directory. Also when a custom distribution download produced a single artifact instead of an unpacked tree, or a previous run left a corrupt extraction behind.
Common situations: Interrupted/cancelled Gradle build left a half-extracted distribution. Distribution plugin misconfigured to a 'tar'/'zip' type whose extraction step was skipped. Symlink in the build dir pointing to a deleted target. Manual tampering with build/testclusters/. Stale caches after switching distribution type or OS.
Related errors
- Failed to create working directory for {}, with: {}
- Can't run bin script: `{}` does not exist. Is this the distr
- Failed to write unicast_hosts for {}
- Can not start {}, missing: {}
- supplied keystore file {} does not exist, require for {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/c215fe9c0687d547.
Report an issue: GitHub.