quarkusio/quarkus · error · IllegalStateException
Multiple GeneratedClassBuildItem were produced for the same
Error message
Multiple GeneratedClassBuildItem were produced for the same classes:
${duplicates} What it means
AbstractJarBuilder.checkConsistency throws this IllegalStateException when multiple GeneratedClassBuildItem build items were produced for the same fully qualified class name during packaging. Duplicate generated classes would silently overwrite each other, so the jar builder detects duplicates and fails with a list of the offending classes and their producers.
Source
Thrown at core/deployment/src/main/java/io/quarkus/deployment/pkg/jar/AbstractJarBuilder.java:104
this.jvmRequirements = jvmRequirements;
checkConsistency(generatedClasses);
}
private static void checkConsistency(List<GeneratedClassBuildItem> generatedClasses) {
Map<String, Long> generatedClassOccurrences = generatedClasses.stream()
.sorted(Comparator.comparing(GeneratedClassBuildItem::binaryName))
.collect(Collectors.groupingBy(GeneratedClassBuildItem::binaryName, Collectors.counting()));
StringBuilder duplicates = new StringBuilder();
for (Entry<String, Long> generatedClassOccurrence : generatedClassOccurrences.entrySet()) {
if (generatedClassOccurrence.getValue() < 2) {
continue;
}
duplicates.append("- ").append(generatedClassOccurrence.getKey()).append(": ")
.append(generatedClassOccurrence.getValue()).append("\n");
}
if (!duplicates.isEmpty()) {
throw new IllegalStateException(
"Multiple GeneratedClassBuildItem were produced for the same classes:\n\n" + duplicates);
}
}
/**
* Copy files from {@code archive} to {@code fs}, filtering out service providers into the given map.
*
* @param archive the root application archive
* @param archiveCreator the archive creator
* @param services the services map
* @throws IOException if an error occurs
*/
protected static void copyFiles(ApplicationArchive archive, ArchiveCreator archiveCreator,
Map<String, List<byte[]>> services,
Predicate<String> ignoredEntriesPredicate) throws IOException {
try {
Map<String, Path> pathsToCopy = new TreeMap<>();
archive.accept(tree -> {View on GitHub (pinned to e1c734241f)
Solutions
- Identify the duplicate class and its producing steps from the list in the message.
- Remove or rename one of the generators (change the generated class's package/name) so names are unique.
- Resolve conflicting/duplicate extension versions in the dependency tree (mvn dependency:tree) and exclude the redundant extension.
Example fix
// before (two build steps) generate(new GeneratedClassBuildItem(true, "com.app.MyConfig", bytes)); // extension also generates com.app.MyConfig // after generate(new GeneratedClassBuildItem(true, "com.app.MyCustomConfig", bytes));
Defensive patterns
Strategy: validation
Validate before calling
Map<String,Integer> seen = new HashMap<>();
seen.merge(generatedClassName, 1, Integer::sum);
if (seen.get(generatedClassName) > 1) {
throw new IllegalStateException("Generated class already produced: " + generatedClassName);
} Try / catch
try {
buildJar();
} catch (IllegalStateException e) {
if (e.getMessage().startsWith("Multiple GeneratedClassBuildItem")) {
LOG.error("Conflicting extensions generate the same class; review the listed producers and exclude one");
}
throw e;
} Prevention
- Namespace generated classes with a package unique to your extension.
- Run mvn dependency:tree to detect duplicated/conflicting extensions.
- In custom build steps, check whether a class was already generated before producing it.
When it happens
Trigger: Two extensions (or two build steps) each producing a GeneratedClassBuildItem with the same class name in a single application build; checkConsistency groups generated classes by name and throws if any name occurs more than once.
Common situations: Using two third-party Quarkus extensions that generate the same support class; a custom build step that produces a class also generated by an extension; running a build with duplicated/old extension versions on the classpath.
Related errors
- Failed to open path tree with root %s
- Dev services for ${request.getName()} requires a startable s
- Name cannot start with '/':${name}
- The class (${name}) cannot be created during deployment.
- Use GeneratedServiceProviderBuildItem to register service pr
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/cb2a049d3380f3fe.
Report an issue: GitHub.