elastic/elasticsearch · error · GradleException
module-info.class no found in ${path}
Error message
module-info.class no found in ${path} What it means
Thrown as GradleException by assertAllESJarsAreModular() when an Elasticsearch JAR (name starting 'elasticsearch-', excluding elasticsearch-log4j) in the lib/ directory does not contain a module-info.class entry at its root. ES server jars must be modular JPMS modules; a missing module-info means the jar was built without module info, breaking the module system checks and runtime module resolution. Note: the message has a typo ('no found' instead of 'not found').
Source
Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java:119
try {
assertAllESJarsAreModular(libPath);
assertAllModulesPresent(libPath);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
});
});
}
/** Checks that all expected ES jar files are modular, i.e. contain a module-info.class in their root. */
private static void assertAllESJarsAreModular(Path libPath) throws IOException {
try (var s = Files.walk(libPath, 1)) {
s.filter(Files::isRegularFile).filter(isESJar).filter(isNotExcluded).sorted().forEach(path -> {
try (JarFile jf = new JarFile(path.toFile())) {
JarEntry entry = jf.getJarEntry(MODULE_INFO);
if (entry == null) {
throw new GradleException(MODULE_INFO + " no found in " + path);
}
} catch (IOException e) {
throw new GradleException("Failed when reading jar file " + path, e);
}
});
}
}
/** Checks that all expected Elasticsearch modules are present. */
private static void assertAllModulesPresent(Path libPath) {
List<String> actualESModules = ModuleFinder.of(libPath).findAll().stream().filter(isESModule).map(toName).sorted().toList();
if (actualESModules.equals(EXPECTED_ES_SERVER_MODULES) == false) {
throw new GradleException(
"expected modules " + listToString(EXPECTED_ES_SERVER_MODULES) + ", \nactual modules " + listToString(actualESModules)
);
}
}
View on GitHub (pinned to db6a809a66)
Solutions
- Add a module-info.java to the source set of the project producing the offending jar.
- Ensure the project applies the ES module/plugin conventions that generate module-info.class during jar task.
- If the jar is legitimately non-modular, add its name prefix to ES_JAR_EXCLUDES (currently only elasticsearch-log4j).
- Rebuild the jar task and verify with 'jar tf <jar> | grep module-info.class'.
Example fix
// before: new subproject jar lacks module-info
evaluationDependsOn(':libs:elasticsearch-newlib')
// jar contains no module-info.class → throws
// after: add module-info.java to src/main/java
// module org.elasticsearch.newlib { exports org.elasticsearch.newlib; }
// and ensure the jar task includes it (default for src/main/java) Defensive patterns
Strategy: validation
Validate before calling
try (JarFile jf = new JarFile(path.toFile())) {
if (jf.getJarEntry("module-info.class") == null) {
System.err.println("WARNING: " + path + " is not modular (no module-info.class)");
}
} Prevention
- Add module-info.java to every ES subproject that produces a jar shipped in lib/.
- Apply the ES module conventions plugin to new subprojects.
- If a jar is intentionally non-modular, add its prefix to ES_JAR_EXCLUDES.
- Run 'jar tf <jar> | grep module-info' after adding new jars to the distribution.
When it happens
Trigger: assertAllESJarsAreModular (line 113) walks lib/ depth 1, filters for regular files starting with 'elasticsearch-' (excluding 'elasticsearch-log4j'), opens each as a JarFile, and checks getJarEntry("module-info.class"). A null entry throws at line 119.
Common situations: A new ES subproject jar was added to the distribution but its build.gradle doesn't apply the module plugin or generate module-info; a third-party shadow jar was renamed to start with 'elasticsearch-'; the modularization step was skipped in the build; refactoring merged a module into a non-modular jar.
Related errors
- expected modules ${listToString(EXPECTED_ES_SERVER_MODULES)}
- Automatic-Module-Name: {e.getMessage()}
- unexpected jar name: {jarName}
- Cannot set Elasticsearch Distribution type to ${type}. Type
- distribution type [${typeName}] for elasticsearch distributi
AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12).
Data as JSON: /api/errors/1c6414a16c9152af.
Report an issue: GitHub.