elastic/elasticsearch · error · GradleException

expected modules ${listToString(EXPECTED_ES_SERVER_MODULES)}

Error message

expected modules ${listToString(EXPECTED_ES_SERVER_MODULES)}, 
actual modules ${listToString(actualESModules)}

What it means

Thrown as GradleException by assertAllModulesPresent() when the set of ES modules discovered by ModuleFinder.of(libPath).findAll() (filtered to names starting 'org.elasticsearch') does not exactly equal EXPECTED_ES_SERVER_MODULES. This is an exact-set equality check — any added, removed, or renamed module fails it. The constant list is the authoritative manifest of modules that must ship in the ES server distribution.

Source

Thrown at build-tools-internal/src/main/java/org/elasticsearch/gradle/internal/InternalDistributionModuleCheckTaskProvider.java:132

        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)
            );
        }
    }

    // ####: eventually assert hashes, etc

    static String listToString(List<String> list) {
        return list.stream().sorted().collect(joining("\n  ", "[\n  ", "]"));
    }
}

View on GitHub (pinned to db6a809a66)

Solutions

  1. Compare the 'expected' vs 'actual' lists in the error message — the diff shows exactly which module was added or removed.
  2. If a module was legitimately added, append its name to EXPECTED_ES_SERVER_MODULES in this file (line 52).
  3. If a module is unexpectedly missing, investigate why its jar didn't build or isn't in lib/ (check the jar task and distribution assembly).
  4. If a module was renamed, update both the module-info.java and EXPECTED_ES_SERVER_MODULES to the new name.

Example fix

// before: new module org.elasticsearch.newfeature built but not in expected list
// throws: expected modules [...], actual modules [...org.elasticsearch.newfeature...]

// after: add the module name to the expected list
private static final List<String> EXPECTED_ES_SERVER_MODULES = List.of(
    // ...
    "org.elasticsearch.newfeature",
    "org.elasticsearch.xcontent"
);
Defensive patterns

Strategy: validation

Validate before calling

List<String> actual = ModuleFinder.of(libPath).findAll().stream()
    .map(m -> m.descriptor().name()).filter(n -> n.startsWith("org.elasticsearch")).sorted().toList();
List<String> missing = new ArrayList<>(EXPECTED_ES_SERVER_MODULES); missing.removeAll(actual);
List<String> extra = new ArrayList<>(actual); extra.removeAll(EXPECTED_ES_SERVER_MODULES);
if (missing.isEmpty() == false || extra.isEmpty() == false) {
    System.err.println("Module mismatch — missing: " + missing + ", extra: " + extra);
}

Prevention

When it happens

Trigger: assertAllModulesPresent (line 129) collects actual module names, sorts, and compares with .equals against the static EXPECTED_ES_SERVER_MODULES list (line 52). A new module added without updating the list, a module renamed, or a module missing from the build all cause inequality and throw.

Common situations: A new ES module was added to the build (e.g., org.elasticsearch.newfeature) but EXPECTED_ES_SERVER_MODULES wasn't updated; a module was renamed or removed; a module failed to build and is absent from lib/; a module was accidentally split into two.

Related errors


AI-assisted analysis of elastic/elasticsearch@db6a809a66 (2026-08-12). Data as JSON: /api/errors/33ee78d8bdcbf553. Report an issue: GitHub.