quarkusio/quarkus · error · IllegalStateException

Boot module listed in model is missing from the module index

Error message

Boot module listed in model is missing from the module index

What it means

During image staging, JLinkSteps.stageOutput builds a map of boot module paths and looks each boot module declared in the modularity model up in the index of resolved modules. If a boot module listed in the model cannot be found among the indexed module descriptors, the build is aborted. This indicates the modularity model and the jlink module index are out of sync.

Source

Thrown at extensions/packaging/jlink/deployment/src/main/java/io/quarkus/jlink/deployment/JLinkSteps.java:94

    public JLinkStagedOutputItem stageOutput(
            CurateOutcomeBuildItem curateOutcome,
            ApplicationModuleInfoBuildItem moduleInfoItem) throws IOException {

        // gather information we'll need
        AppModuleModel model = moduleInfoItem.model();
        Map<String, ModuleInfo> modulesByName = model.modulesByName();

        // create the staging directory
        final Path staging = config.outputDirectory().resolve(config.stagingDirectory());
        Files.createDirectories(staging);

        // create a mapping for each boot module path
        final Map<String, Path> bmp = new HashMap<>();
        for (String moduleName : model.bootModules()) {
            // get this boot module descriptor
            ModuleInfo moduleInfo = modulesByName.get(moduleName);
            if (moduleInfo == null) {
                throw new IllegalStateException("Boot module listed in model is missing from the module index");
            }
            // our special launcher module
            if (moduleName.equals("io.quarkus.jlink.launcher")) {
                // the list of resources produced by generating the main class
                List<Resource> dynModuleResources = new ArrayList<>();
                // generate the simple main class which runs the launcher with the app module info
                Gizmo gizmo = Gizmo.create((path, bytes) -> dynModuleResources.add(new MemoryResource(path, bytes)));
                gizmo.class_(APP_MAIN, cc -> {
                    cc.public_();
                    cc.staticMethod("main", mc -> {
                        mc.public_();
                        ParamVar args = mc.parameter("args", String[].class);
                        mc.body(b0 -> {
                            b0.invokeStatic(
                                    MethodDesc.of(JLinkAppLauncher.class, "run", void.class, String.class, String[].class),
                                    Const.of(moduleInfoItem.model().appModuleInfo().name()),
                                    args);
                            b0.return_();

View on GitHub (pinned to e1c734241f)

Solutions

  1. Run a clean build (./mvnw clean) to eliminate stale incremental build state
  2. Verify every module listed as a boot module in the jlink configuration actually exists in the application's resolved module graph
  3. Check that jlink extension and modular-jlink build items are from compatible versions (no mixed artifact versions)
  4. Inspect the modularity model build step output to see which boot modules were recorded and why

Example fix

// before: quarkus.jlink.* config referencing a non-existent module
quarkus.jlink.add-modules com.myapp.missing.module
// after: only reference modules that are part of the build
quarkus.jlink.add-modules com.myapp.existing.module
Defensive patterns

Strategy: validation

Validate before calling

// before running image packaging, verify boot modules are all resolvable
Set<String> indexed = modulesByName.keySet();
List<String> missing = model.bootModules().stream()
        .filter(m -> !indexed.contains(m))
        .toList();
if (!missing.isEmpty()) throw new IllegalStateException("Boot modules missing from index: " + missing);

Type guard

boolean isBootModuleIndexed(String name, Map<String, ModuleInfo> modulesByName) {
    return name != null && modulesByName.containsKey(name);
}

Try / catch

try {
    stageOutput(config, model, modulesByName);
} catch (IllegalStateException e) {
    if (e.getMessage().contains("missing from the module index")) {
        throw new IllegalStateException("Stale/inconsistent modularity model; run a clean build", e);
    }
    throw e;
}

Prevention

When it happens

Trigger: model.bootModules() contains a module name that has no ModuleInfo entry in modulesByName — e.g. the model recorded a boot module that was never resolved/indexed as a module descriptor during the build steps.

Common situations: Custom jlink configuration adding boot modules that do not exist in the application's module graph; a stale or corrupted incremental build where the module index was built with different dependencies; upstream changes to the modular-jlink build items between extensions.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/e4ee9bf13991b64a. Report an issue: GitHub.