quarkusio/quarkus · error · RuntimeException

More than one @QuarkusMain method found with name '${name}':

Error message

More than one @QuarkusMain method found with name '${name}': ${classInfo.name()} and ${quarkusMainAnnotations.get(name)}

What it means

@QuarkusMain allows naming an entry point via its 'name' attribute. While indexing all @QuarkusMain annotations, MainClassBuildStep builds a name -> class map; encountering a second annotated class with the same name throws this RuntimeException to avoid ambiguity in -Dquarkus.main-class resolution.

Source

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

    public MainClassBuildItem mainClassBuildStep(BuildProducer<GeneratedClassBuildItem> generatedClass,
            BuildProducer<BytecodeTransformerBuildItem> transformedClass,
            CombinedIndexBuildItem combinedIndexBuildItem,
            Optional<QuarkusApplicationClassBuildItem> quarkusApplicationClass,
            PackageConfig packageConfig) {
        String mainClassName = MAIN_CLASS;
        Map<String, String> quarkusMainAnnotations = new HashMap<>();
        IndexView index = combinedIndexBuildItem.getIndex();
        Collection<AnnotationInstance> quarkusMains = index
                .getAnnotations(DotName.createSimple(QuarkusMain.class.getName()));
        for (AnnotationInstance i : quarkusMains) {
            AnnotationValue nameValue = i.value("name");
            String name = "";
            if (nameValue != null) {
                name = nameValue.asString();
            }
            ClassInfo classInfo = i.target().asClass();
            if (quarkusMainAnnotations.containsKey(name)) {
                throw new RuntimeException(
                        "More than one @QuarkusMain method found with name '" + name + "': "
                                + classInfo.name() + " and " + quarkusMainAnnotations.get(name));
            }
            quarkusMainAnnotations.put(name, sanitizeMainClassName(classInfo, index));
        }

        MethodInfo mainClassMethod = null;
        if (packageConfig.mainClass().isPresent()) {
            String mainAnnotationClass = quarkusMainAnnotations.get(packageConfig.mainClass().get());
            if (mainAnnotationClass != null) {
                mainClassName = mainAnnotationClass;
            } else {
                mainClassName = packageConfig.mainClass().get();
            }
        } else if (quarkusMainAnnotations.containsKey("")) {
            mainClassName = quarkusMainAnnotations.get("");
        }
        if (mainClassName.equals(MAIN_CLASS)) {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Give each @QuarkusMain annotation a unique name value
  2. If you intend the default main, keep exactly one @QuarkusMain without a name and name all others
  3. Rename or delete the duplicated entry class
  4. Run a project-wide search for @QuarkusMain to audit all names

Example fix

// before
@QuarkusMain(name="run") public class MainA { ... }
@QuarkusMain(name="run") public class MainB { ... }
// after
@QuarkusMain(name="run-a") public class MainA { ... }
@QuarkusMain(name="run-b") public class MainB { ... }
Defensive patterns

Strategy: validation

Validate before calling

Set<String> seen = new HashSet<>();
for (Class<?> c : allAnnotatedClasses) {
    QuarkusMain qm = c.getAnnotation(QuarkusMain.class);
    String name = qm.name().isEmpty() ? "" : qm.name();
    if (!seen.add(name)) {
        throw new IllegalStateException("Duplicate @QuarkusMain name: '" + name + "'");
    }
}

Try / catch

try {
    quarkusBuild();
} catch (RuntimeException e) {
    if (e.getMessage() != null && e.getMessage().startsWith("More than one @QuarkusMain method found")) {
        // rename one of the listed classes' @QuarkusMain name
    }
    throw e;
}

Prevention

When it happens

Trigger: During mainClassBuildStep, an AnnotationInstance target class yields a name that is already a key in quarkusMainAnnotations — two classes (or methods) annotated @QuarkusMain(name="same") or both with the empty default name.

Common situations: Two CLI entry classes annotated with the same @QuarkusMain name; two @QuarkusMain classes both left without an explicit name (both map to ""); copy-pasting a main class and forgetting to change the name attribute.

Related errors


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