elastic/elasticsearch · critical · TestClustersException

Can not start {}, missing: {}

Error message

Can not start {}, missing: {}

What it means

TestClustersException thrown at the top of ElasticsearchNode.start() when the extracted distribution directory does not exist. start() requires the ES distribution to have been downloaded/unpacked into getExtractedDistributionDir(); its absence means the distribution-resolution step did not run or failed.

Source

Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:472

    public void freeze() {
        requireNonNull(testDistribution, "null testDistribution passed when configuring test cluster `" + this + "`");
        LOGGER.info("Locking configuration of `{}`", this);
        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);
                    }
                }

View on GitHub (pinned to db6a809a66)

Solutions

  1. Ensure start() is invoked through the testclusters lifecycle (useCluster / dependsOn wiring) so the extraction task runs first.
  2. Check the path printed in the message; if missing, run the distro-extraction task (e.g. ./gradlew <taskName>Download) or clean and re-run.
  3. Verify the distribution version/type resolves — inspect testDistribution and the version configuration; check network/auth for snapshot distributions.
  4. If working dir was wiped, remove build/testclusters and rerun the test to re-trigger extraction.

Example fix

// before
tasks.register('customStart') {
  doFirst { testClusters.cluster.singleNode().start() }  // distro not extracted yet
}

// after
tasks.register('customStart') {
  dependsOn testClusters.cluster  // ensures extraction runs first
  doFirst { testClusters.cluster.singleNode().start() }
}
Defensive patterns

Strategy: validation

Validate before calling

Path distro = node.getExtractedDistributionDir();
if (!Files.isDirectory(distro)) {
    throw new IllegalStateException("Distribution not extracted at " + distro
        + " — dependsOn the extraction task first");
}
node.start();

Try / catch

try {
    node.start();
} catch (TestClustersException e) {
    if (e.getMessage().contains("missing")) {
        // trigger extraction then retry once
        throw new IllegalStateException("Distribution missing — rerun extraction task", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: node.start() is called but Files.exists(getExtractedDistributionDir()) is false — the archive was never fetched/extracted, was deleted, or extraction ran in a different working dir.

Common situations: A custom test task invokes start() without depending on the distribution-extraction task; the build/testclusters dir was cleaned mid-run; the distribution could not be resolved (auth, network, wrong version) and the dir was never populated; the path points outside the project workspace.

Related errors


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