elastic/elasticsearch · error · IllegalArgumentException
Not a valid module {} for {}
Error message
Not a valid module {} for {} What it means
Thrown by installModules() when a module Provider<File> resolves to neither a .zip (case-insensitive) nor a directory. The node cannot install such an artifact into <distro>/modules and rejects it with IllegalArgumentException, signalling a configuration error in the module dependency.
Source
Thrown at build-tools/src/main/java/org/elasticsearch/gradle/testclusters/ElasticsearchNode.java:707
}
});
}
}
private void installModules() {
logToProcessStdout("Installing " + modules.size() + " modules");
for (Provider<File> module : modules) {
Path destination = getDistroDir().resolve("modules")
.resolve(module.get().getName().replace(".zip", "").replace("-" + getVersion(), "").replace("-SNAPSHOT", ""));
// only install modules that are not already bundled with the integ-test distribution
if (Files.exists(destination) == false) {
fileSystemOperations.copy(spec -> {
if (module.get().getName().toLowerCase().endsWith(".zip")) {
spec.from(archiveOperations.zipTree(module));
} else if (module.get().isDirectory()) {
spec.from(module);
} else {
throw new IllegalArgumentException("Not a valid module " + module + " for " + this);
}
spec.into(destination);
});
}
}
}
@Override
public void extraConfigFile(String destination, File from) {
if (destination.contains("..")) {
throw new IllegalArgumentException("extra config file destination can't be relative, was " + destination + " for " + this);
}
extraConfigFiles.put(destination, from);
}
@Override
public void extraConfigFile(String destination, File from, PropertyNormalization normalization) {
if (destination.contains("..")) {View on GitHub (pinned to db6a809a66)
Solutions
- Inspect the offending module path printed in the message.
- Ensure the module dependency produces a .zip (or is a directory in dev runs): use the integ-test distribution zip of the module.
- Declare the dependency with the correct type, e.g. group:..., name:'my-module', version:..., type:'zip'.
- Invalidate the Gradle cache for that artifact (--refresh-dependencies) if you recently changed its type.
Example fix
// before: returns a jar/pom artifact
module(project(':my-module').configurations.archives)
// after: use the integ-test zip distribution of the module
module(project(':my-module').ext.distZip)
// or coordinate with explicit type
// dependencies { dists group:'org.elasticsearch.module', name:'my-module', version:'8.15.0', ext:'zip' } Defensive patterns
Strategy: type-guard
Validate before calling
// Validate every module provider yields a zip or directory before start
for (Provider<File> m : node.getModules()) {
File f = m.get();
String n = f.getName().toLowerCase();
if (!n.endsWith(".zip") && !f.isDirectory()) {
throw new IllegalStateException("Module artifact is neither zip nor dir: " + f);
}
} Type guard
// Only zip-producing or directory configurations are valid module inputs
static Provider<File> asModuleArtifact(TaskProvider<? extends Task> zipTask) {
return zipTask.flatMap(t -> t.getOutputs().getFiles().getSingleFile().toPath().toFile());
} Prevention
- Declare module dependencies with type:'zip' or ext:'zip'.
- Use the module's integ-test-zip distribution, not its jar.
- Invalidate Gradle cache after changing artifact type.
When it happens
Trigger: Calling module(provider) where the provider resolves to a pom, a tar, a .jar, or a missing/unrecognised artifact. Typically the wrong Gradle configuration or artifact type is wired up (e.g. a dependency declared with type 'pom' or 'tar' instead of 'zip').
Common situations: Maven coordinate for the module declared with the wrong type/classifier. Configuration returning the sources or pom artifact. Module project whose main output is a directory in dev mode but a zip in CI, with a configuration that returns neither. Stale artifact in cache after switching type.
Related errors
- extra jar file {} doesn't appear to be a JAR
- 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/a4186197f8911f66.
Report an issue: GitHub.