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.
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)
Solutions
- Identify which extensions produce the duplicate name from the build output and remove one of the extensions/forks
- If it's your own build step, rename the feature string to a unique value
- Upgrade/align extension versions — older collisions are usually fixed in newer releases
- 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
- Give custom FeatureBuildItems unique, project-prefixed names
- Avoid including two forks of the same extension
- Keep third-party extensions updated where name collisions were fixed
- Grep your build steps for FeatureBuildItem names when adding extensions
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
- capabilityErrors.report()
- Failed to open path tree with root %s
- %s is marked @Record but does not inject an @Recorder object
- Unknown recorder constructor parameter: %s in recorder %s
- Dev services for ${request.getName()} requires a startable s
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/c12ee93be83660b8.
Report an issue: GitHub.