elastic/elasticsearch · error · TestClustersException
Can't create extra config file from {} for {} as it does not
Error message
Can't create extra config file from {} for {} as it does not exist What it means
Thrown by copyExtraConfigFiles() during start() when an entry registered via extraConfigFile(destination, from) points to a source File whose path does not exist (Files.exists check). The node refuses to copy a non-existent file into its config directory because that would silently produce a missing config entry and a confusing downstream startup failure.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:618
if (currentDistro + 1 >= distributions.size()) {
throw new TestClustersException("Ran out of versions to go to for " + this);
}
logToProcessStdout("Switch version from " + getVersion() + " to " + distributions.get(currentDistro + 1).getVersion());
currentDistro += 1;
setting("node.attr.upgraded", "true");
}
private boolean isSettingTrue(String name) {
return Boolean.parseBoolean(settings.getOrDefault(name, "false").toString());
}
private void copyExtraConfigFiles() {
if (extraConfigFiles.isEmpty() == false) {
logToProcessStdout("Setting up " + extraConfigFiles.size() + " additional config files");
}
extraConfigFiles.forEach((destination, from) -> {
if (Files.exists(from.toPath()) == false) {
throw new TestClustersException("Can't create extra config file from " + from + " for " + this + " as it does not exist");
}
Path dst = configFile.getParent().resolve(destination);
try {
Files.createDirectories(dst.getParent());
Files.copy(from.toPath(), dst, StandardCopyOption.REPLACE_EXISTING);
LOGGER.info("Added extra config file {} for {}", destination, this);
} catch (IOException e) {
throw new UncheckedIOException("Can't create extra config file for", e);
}
});
}
/**
* Copies extra jars to the `/lib` directory.
* //TODO: Remove this when system modules are available
*/
private void copyExtraJars() {
List<File> extraJarFiles = this.extraJarConfigurations.stream()View on GitHub (pinned to db6a809a66)
Solutions
- Verify the path from the message exists at the moment the cluster starts.
- If generated, pass a Provider<File> or wire the producing task as a dependency so Gradle materialises it first.
- Use project.layout.projectDirectory.file('config/x.xml') for checked-in files to make the path unambiguous.
- Remove the extraConfigFile call if the file is no longer needed; do not register dead config.
Example fix
// before: file does not exist yet
extraConfigFile('log4j2.xml', new File('src/test/resources/log4j2.xml'))
// after: resolve from project dir and ensure the file is committed
extraConfigFile('log4j2.xml', project.layout.projectDirectory.file('src/test/resources/log4j2.xml').asFile) Defensive patterns
Strategy: validation
Validate before calling
node.getExtraConfigFiles().forEach((dest, from) -> {
if (!Files.exists(from.toPath())) {
throw new IllegalStateException("extraConfigFile source missing for dest " + dest + ": " + from);
}
});
// Prefer Provider<File> sourced from the producing task so Gradle materialises it before start(). Prevention
- Use project.layout.projectDirectory.file(...) for checked-in config.
- Wire generated config through task outputs.
- Do not register extraConfigFile entries you no longer need.
When it happens
Trigger: Calling extraConfigFile('log4j2.xml', file) where file resolves to a path that does not exist at start time. Because the map stores File references lazily, the check fires during start() rather than at registration, so a typo or a not-yet-generated source surfaces here.
Common situations: Source config file generated by another Gradle task that was not wired as a dependency. Path relative to the wrong subproject. Typo in filename. Resource stripped on a branch. CI checkout missing the file.
Related errors
- supplied keystore file {} does not exist, require for {}
- Can't create extra config file for
- extra jar file {} doesn't appear to be a JAR
- Can't create roles.yml config file from {} for {} as it does
- Not a valid module {} for {}
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/f28e98b984694b35.
Report an issue: GitHub.