elastic/elasticsearch · error · FindException

automatic module without a manifest name is not supported, f

Error message

automatic module without a manifest name is not supported, for: {path}

What it means

Thrown as a FindException by EmbeddedModulePath.descriptorForAutomatic when an automatic module's JAR has no Automatic-Module-Name manifest attribute and no module-info. Elasticsearch's embedded-module path requires automatic modules to declare a manifest name; the fallback to a jar-name-derived module name (which the JDK allows) is deliberately not supported here. FindException signals a module-resolution failure during layer construction.

Source

Thrown at libs/core/src/main/java/org/elasticsearch/core/internal/provider/EmbeddedModulePath.java:62

            Optional<ModuleDescriptor> vmd = getModuleInfoVersioned(path);
            if (vmd.isPresent()) {
                return vmd.get();
            } else if (hasRootModuleInfo(path)) {
                return readModuleInfo(path.resolve(MODULE_INFO), path);
            } else {
                return descriptorForAutomatic(path);
            }
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }

    // Generates and returns a module descriptor for an automatic module at the given path.
    // Currently, only automatic modules with a manifest name are supported.
    private static ModuleDescriptor descriptorForAutomatic(Path path) throws IOException {
        String moduleName = moduleNameFromManifestOrNull(path);
        if (moduleName == null) {
            throw new FindException("automatic module without a manifest name is not supported, for: " + path);
        }
        ModuleDescriptor.Builder builder;
        try {
            builder = ModuleDescriptor.newAutomaticModule(moduleName);
        } catch (IllegalArgumentException e) {
            throw new FindException(AUTOMATIC_MODULE_NAME + ": " + e.getMessage());
        }

        version(path.getFileName().toString()).ifPresent(builder::version);

        // scan the names of the entries in the exploded JAR
        var scan = scan(path);

        // all packages are exported and open, since the auto-module bit is set
        String separator = path.getFileSystem().getSeparator();
        builder.packages(
            scan.classFiles().stream().map(cf -> toPackageName(cf, separator)).flatMap(Optional::stream).collect(Collectors.toSet())
        );

View on GitHub (pinned to db6a809a66)

Solutions

  1. Add `Automatic-Module-Name: <stable.name>` to the embedded jar's MANIFEST.MF.
  2. If you own the jar, add the attribute in its Gradle/Maven build (jar { manifest { attributes('Automatic-Module-Name': '...') } }).
  3. If the jar is a true module, add a module-info.class instead so descriptorFor takes the module-info branch.
  4. Confirm the jar is meant to be a module-mode provider; non-module providers should not be routed through EmbeddedModulePath.

Example fix

// before — embedded jar has no manifest attribute

// after — in the jar's Gradle build
jar {
    manifest {
        attributes('Automatic-Module-Name': 'org.example.mylib')
    }
}
Defensive patterns

Strategy: validation

Validate before calling

// Pre-check a jar for an Automatic-Module-Name (or module-info) before module-mode loading
boolean isModuleCapableJar(Path jar) throws IOException {
    try (JarFile j = new JarFile(jar.toFile())) {
        if (j.getEntry("module-info.class") != null) return true;
        Manifest m = j.getManifest();
        return m != null && m.getMainAttributes().getValue("Automatic-Module-Name") != null;
    }
}

Type guard

static boolean hasAutomaticModuleName(Path jar) throws IOException {
    try (JarFile j = new JarFile(jar.toFile())) {
        Manifest m = j.getManifest();
        return m != null && m.getMainAttributes().getValue("Automatic-Module-Name") != null;
    }
}

Try / catch

try {
    return EmbeddedModulePath.descriptorFor(path);
} catch (FindException e) {
    if (e.getMessage().contains("manifest name")) {
        // fix: add Automatic-Module-Name to the jar's manifest; do not silently skip
        throw new RuntimeException("jar missing Automatic-Module-Name: " + path, e);
    }
    throw e;
}

Prevention

When it happens

Trigger: Loading an embedded provider jar as a module when that jar lacks both module-info.class and an Automatic-Module-Name manifest entry. The descriptorFor path reaches descriptorForAutomatic only after the versioned module-info and root module-info checks fail.

Common situations: Vendoring a third-party dependency as an embedded impl jar without adding the manifest attribute. Upgrading a dependency whose newer build dropped the manifest. A custom build that strips manifest attributes during shading. Mixing module-mode providers with classic jars.

Related errors


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