elastic/elasticsearch · error · IllegalArgumentException
extra jar file {} doesn't appear to be a JAR
Error message
extra jar file {} doesn't appear to be a JAR What it means
Thrown by copyExtraJars() when a File obtained from an extraJarFiles FileCollection does not end with '.jar'. The node copies extra jars into <distro>/lib and rejects anything that is not obviously a jar to avoid corrupting the classpath. The exception type is IllegalArgumentException (not TestClustersException), signalling a programming/configuration error rather than a runtime cluster fault.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:645
}
});
}
/**
* Copies extra jars to the `/lib` directory.
* //TODO: Remove this when system modules are available
*/
private void copyExtraJars() {
List<File> extraJarFiles = this.extraJarConfigurations.stream()
.flatMap(fileCollection -> fileCollection.getFiles().stream())
.toList();
if (extraJarFiles.isEmpty() == false) {
logToProcessStdout("Setting up " + this.extraJarConfigurations.size() + " additional jar dependencies");
}
extraJarFiles.forEach(from -> {
if (from.getName().endsWith(".jar") == false) {
throw new IllegalArgumentException("extra jar file " + from + " doesn't appear to be a JAR");
}
Path destination = getDistroDir().resolve("lib").resolve(from.getName());
try {
Files.copy(from.toPath(), destination, StandardCopyOption.REPLACE_EXISTING);
LOGGER.info("Added extra jar {} to {}", from.getName(), destination);
} catch (IOException e) {
throw new UncheckedIOException("Can't copy extra jar dependency " + from.getName() + " to " + destination, e);
}
});
}
private void configureSecurity() {
if (credentials.isEmpty() == false) {
logToProcessStdout("Setting up " + credentials.size() + " users");
credentials.forEach(
paramMap -> runElasticsearchBinScript(View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the offending path printed in the message and confirm it should be a jar.
- Use the correct configuration: a runtime classpath whose artifacts end with .jar (e.g. project.configurations.runtimeClasspath filtered to .jar).
- If you genuinely need a non-jar on the classpath, package it as a jar first.
- Filter the FileCollection before passing: configurations.myConfig.filter { it.name.endsWith('.jar') }.
Example fix
// before: passes a configuration that contains pom/sources
extraJarFiles(configurations.implementation)
// after: filter to jars only
extraJarFiles(configurations.implementation.filter { it.name.endsWith('.jar') }) Defensive patterns
Strategy: type-guard
Validate before calling
// Filter any FileCollection to jars before registering
FileCollection jars = myConfig.filter(f -> f.getName().toLowerCase().endsWith(".jar"));
node.extraJarFiles(jars); Type guard
// Type guard: only jars are valid inputs to extraJarFiles
static FileCollection onlyJars(FileCollection in) {
return in.filter(f -> f.getName().toLowerCase().endsWith(".jar"));
} Prevention
- Pass runtime classpath configurations filtered to .jar.
- Avoid passing 'sources', 'javadoc', or 'pom' configurations.
- If a non-jar must be on the classpath, package it as a jar first.
When it happens
Trigger: Calling extraJarFiles(from) with a FileCollection that resolves to a non-jar artifact: a pom, sources jar classifier stripped by mistake, a directory, a zip, or a plain class file. Often happens when a configuration is mistyped (e.g. using 'runtimeClasspath' or 'sources' instead of 'runtimeElements').
Common situations: Mistakenly passing a sources/javadoc configuration. A third-party dependency whose artifact lacks the .jar extension. A test fixture that bundles classes in a directory. Shadow/fat-jar task output named without .jar.
Related errors
- Not a valid module {} for {}
- Can't create extra config file from {} for {} as it does not
- extra config file destination can't be relative, was {} for
- Unknown keys in user definition {} for {}
- Invalid system property `{}`. Use `requiresFeature` instead.
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/85267e38b83b87e9.
Report an issue: GitHub.