{"record":{"id":"ea6fafa0a13effb7","repo":"elastic/elasticsearch","slug":"ran-out-of-versions-to-go-to-for","errorCode":null,"errorMessage":"Ran out of versions to go to for {}","messagePattern":"Ran out of versions to go to for (.+?)","errorType":"exception","errorClass":"TestClustersException","httpStatus":null,"severity":"error","filePath":"build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java","lineNumber":601,"sourceCode":"                \"[\" + Instant.now().toString() + \"] [BUILD] \" + message + \"\\n\",\n                StandardOpenOption.CREATE,\n                StandardOpenOption.APPEND\n            );\n        } catch (IOException e) {\n            throw new UncheckedIOException(e);\n        }\n    }\n\n    @Override\n    public void restart() {\n        LOGGER.info(\"Restarting {}\", this);\n        stop(false);\n        start();\n    }\n\n    void goToNextVersion() {\n        if (currentDistro + 1 >= distributions.size()) {\n            throw new TestClustersException(\"Ran out of versions to go to for \" + this);\n        }\n        logToProcessStdout(\"Switch version from \" + getVersion() + \" to \" + distributions.get(currentDistro + 1).getVersion());\n        currentDistro += 1;\n        setting(\"node.attr.upgraded\", \"true\");\n    }\n\n    private boolean isSettingTrue(String name) {\n        return Boolean.parseBoolean(settings.getOrDefault(name, \"false\").toString());\n    }\n\n    private void copyExtraConfigFiles() {\n        if (extraConfigFiles.isEmpty() == false) {\n            logToProcessStdout(\"Setting up \" + extraConfigFiles.size() + \" additional config files\");\n        }\n        extraConfigFiles.forEach((destination, from) -> {\n            if (Files.exists(from.toPath()) == false) {\n                throw new TestClustersException(\"Can't create extra config file from \" + from + \" for \" + this + \" as it does not exist\");\n            }","sourceCodeStart":583,"sourceCodeEnd":619,"githubUrl":"https://github.com/elastic/elasticsearch/blob/db6a809a667c081ca1dc7500389d26975573215f/build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java#L583-L619","documentation":"Thrown by goToNextVersion() when currentDistro + 1 >= distributions.size(), i.e. a BWC/upgrade test asks the node to advance to the next registered distribution but none remains. The node carries an ordered list of distributions; this guard prevents an IndexOutOfBounds and signals the test wired too few versions for the number of upgrade steps it performs.","triggerScenarios":"An upgrade task (e.g. RollingUpgradeTask / bwc test) calls node.goToNextVersion() more times than the number of distributions registered via distribution(...) minus one. Commonly hit when a BWC matrix is configured with only the current version but the test plan performs an old->new upgrade requiring at least two.","commonSituations":"BWC test misconfigured with a single distribution. Old version added via bwcVersion but not actually registered in the distributions list. Bug in an upgrade-task loop that calls goToNextVersion unconditionally on every node even when it is already on the final version.","solutions":["Register the missing older distribution(s) on the node: distribution 'integ-test-zip', '<old-version>' before the current version.","If using the bwc plugin, ensure bwcVersionList / the bwc task graph actually adds the distributions; check the test's distributions block.","Review the calling test: only call goToNextVersion() on nodes that have a next version; guard with a check or rely on the framework's rolling-upgrade helper.","Inspect distributions.size() at config time (e.g. add an assertion) to fail fast with a clearer message than the runtime throw."],"exampleFix":"// before: single distribution, upgrade step has nowhere to go\ntestClusters {\n  myNode {\n    distribution 'integ-test-zip', '8.15.0'\n  }\n}\n// after: register old then new so goToNextVersion can advance\ntestClusters {\n  myNode {\n    distribution 'integ-test-zip', '7.17.0'\n    distribution 'integ-test-zip', '8.15.0'\n  }\n}","handlingStrategy":"validation","validationCode":"// At config freeze time, assert enough distributions are registered for upgrade steps\nint needed = expectedUpgradeSteps + 1;\nif (node.getDistributions().size() < needed) {\n    throw new IllegalStateException(\"Node has \" + node.getDistributions().size()\n        + \" distributions but upgrade plan needs \" + needed\n        + \"; register older versions via distribution(...)\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Register BWC versions in ascending order via distribution(...) before the current version.","Guard upgrade loops so goToNextVersion() is only called when a next version exists.","Add a config-time assertion on distributions.size() to fail fast with a clearer message."],"tags":["testclusters","bwc","upgrade","versioning"],"backgroundTag":null,"analyzedSha":"db6a809a667c081ca1dc7500389d26975573215f","analyzedAt":"2026-08-12T01:39:14.192Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}