{"record":{"id":"e9b9d6825ccab7b1","repo":"elastic/elasticsearch","slug":"can-not-start-missing","errorCode":null,"errorMessage":"Can not start {}, missing: {}","messagePattern":"Can not start (.+?), missing: (.+?)","errorType":"exception","errorClass":"TestClustersException","httpStatus":null,"severity":"critical","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java","lineNumber":472,"sourceCode":"    public void freeze() {\n        requireNonNull(testDistribution, \"null testDistribution passed when configuring test cluster `\" + this + \"`\");\n        LOGGER.info(\"Locking configuration of `{}`\", this);\n        distributions.forEach(ElasticsearchDistribution::maybeFreeze);\n        configurationFrozen.set(true);\n    }\n\n    private static String throwableToString(Throwable t) {\n        StringWriter sw = new StringWriter();\n        PrintWriter pw = new PrintWriter(sw);\n        t.printStackTrace(pw);\n        return sw.toString();\n    }\n\n    @Override\n    public synchronized void start() {\n        LOGGER.info(\"Starting `{}`\", this);\n        if (Files.exists(getExtractedDistributionDir()) == false) {\n            throw new TestClustersException(\"Can not start \" + this + \", missing: \" + getExtractedDistributionDir());\n        }\n        if (Files.isDirectory(getExtractedDistributionDir()) == false) {\n            throw new TestClustersException(\"Can not start \" + this + \", is not a directory: \" + getExtractedDistributionDir());\n        }\n\n        try {\n            if (isWorkingDirConfigured == false) {\n                logToProcessStdout(\"Configuring working directory: \" + workingDir);\n                // make sure we always start fresh\n                if (Files.exists(workingDir)) {\n                    if (preserveDataDir) {\n                        try (var files = Files.list(workingDir)) {\n                            files.filter(path -> path.equals(confPathData) == false).forEach(this::uncheckedDeleteWithRetry);\n                        }\n                    } else {\n                        deleteWithRetry(workingDir);\n                    }\n                }","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java#L454-L490","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure start() is invoked through the testclusters lifecycle (useCluster / dependsOn wiring) so the extraction task runs first.","Check the path printed in the message; if missing, run the distro-extraction task (e.g. ./gradlew <taskName>Download) or clean and re-run.","Verify the distribution version/type resolves — inspect testDistribution and the version configuration; check network/auth for snapshot distributions.","If working dir was wiped, remove build/testclusters and rerun the test to re-trigger extraction."],"exampleFix":"// before\ntasks.register('customStart') {\n  doFirst { testClusters.cluster.singleNode().start() }  // distro not extracted yet\n}\n\n// after\ntasks.register('customStart') {\n  dependsOn testClusters.cluster  // ensures extraction runs first\n  doFirst { testClusters.cluster.singleNode().start() }\n}","handlingStrategy":"validation","validationCode":"Path distro = node.getExtractedDistributionDir();\nif (!Files.isDirectory(distro)) {\n    throw new IllegalStateException(\"Distribution not extracted at \" + distro\n        + \" — dependsOn the extraction task first\");\n}\nnode.start();","typeGuard":null,"tryCatchPattern":"try {\n    node.start();\n} catch (TestClustersException e) {\n    if (e.getMessage().contains(\"missing\")) {\n        // trigger extraction then retry once\n        throw new IllegalStateException(\"Distribution missing — rerun extraction task\", e);\n    }\n    throw e;\n}","preventionTips":["Always wire dependsOn the distribution-extraction task before calling start().","Use the testclusters lifecycle (useCluster) rather than manual start() calls.","Don't wipe build/testclusters between tasks in the same run."],"tags":["test","testclusters","lifecycle","distribution"],"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-12T06:17:24.410Z"}