quarkusio/quarkus · error · IllegalStateException

Multiple extensions registered a feature of the same name

Error message

Multiple extensions registered a feature of the same name: ${feature.getName()}

What it means

Each extension normally registers one named FeatureBuildItem for logging/feature reporting. During main-class generation Quarkus collects all features for the startup log line; if two extensions registered a feature with the identical name the build fails fast with this IllegalStateException.

Solutions

  1. Identify which extensions produce the duplicate name from the build output and remove one of the extensions/forks
  2. If it's your own build step, rename the feature string to a unique value
  3. Upgrade/align extension versions — older collisions are usually fixed in newer releases
  4. Report/patch the offending third-party extension to use a distinct feature name

Example fix

// before (custom build step)
return List.of(new FeatureBuildItem("hibernate"));
// after
return List.of(new FeatureBuildItem("my-custom-hibernate-integration"));
Defensive patterns

Strategy: validation

Validate before calling

Set<String> names = new HashSet<>();
for (var f : features) {
    if (!names.add(f.getName())) {
        throw new IllegalStateException("Duplicate feature name: " + f.getName());
    }
}

Try / catch

try {
    quarkusBuild();
} catch (IllegalStateException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("Multiple extensions registered a feature")) {
        // inspect extensions for the duplicated feature name and remove/patch one
    }
    throw e;
}

Prevention

When it happens

Trigger: During MainClassBuildStep.build, iterating features and finding the same feature name twice — two extensions (or one extension twice) produced FeatureBuildItems with equal names.

Common situations: Two different extensions picked the same feature name (often after a rename/merge); an application's custom build step registers a FeatureBuildItem whose name collides with an existing extension (e.g. 'hibernate'); including two forks of the same extension.

Related errors


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

Appendix: source

Thrown at core/deployment/src/main/java/io/quarkus/deployment/steps/MainClassBuildStep.java:336

                    ofMethod(RuntimeInfoProvider.class, "register", void.class, ValueRegistry.class, RuntimeSource.class),
                    runtimeInfoProvider,
                    valueRegistry,
                    tryBlock.invokeStaticMethod(ofMethod(ConfigRuntimeSource.class, "runtimeSource", RuntimeSource.class)));
        }

        for (MainBytecodeRecorderBuildItem holder : mainMethod) {
            writeRecordedBytecode(holder.getBytecodeRecorder(), holder.getGeneratedStartupContextClassName(), substitutions,
                    recordableConstructorBuildItems,
                    loaders, constants, gizmoOutput, startupContext, tryBlock);
        }

        tryBlock.invokeStaticMethod(RUNTIME_EXECUTION_RUNNING);

        // Startup log messages
        List<String> featureNames = new ArrayList<>();
        for (FeatureBuildItem feature : features) {
            if (featureNames.contains(feature.getName())) {
                throw new IllegalStateException(
                        "Multiple extensions registered a feature of the same name: " + feature.getName());
            }
            featureNames.add(feature.getName());
        }
        ResultHandle featuresHandle = tryBlock.load(featureNames.stream().sorted().collect(Collectors.joining(", ")));
        tryBlock.invokeStaticMethod(
                ofMethod(Timing.class, "printStartupTime", void.class, String.class, String.class, String.class, String.class,
                        List.class, boolean.class, boolean.class),
                tryBlock.load(applicationInfo.getName()),
                tryBlock.load(applicationInfo.getVersion()),
                tryBlock.load(Version.getVersion()),
                featuresHandle,
                tryBlock.invokeStaticMethod(ofMethod(ConfigUtils.class, "getProfiles", List.class)),
                tryBlock.load(LaunchMode.DEVELOPMENT.equals(launchMode.getLaunchMode())),
                tryBlock.load(launchMode.isAuxiliaryApplication()));

        tryBlock.invokeStaticMethod(
                ofMethod(QuarkusConsole.class, "start", void.class));

View on GitHub (pinned to e1c734241f)