quarkusio/quarkus · error · BuildException

Too many default routes.

Error message

Too many default routes.

What it means

finalizeRouter expects at most one DefaultRouteBuildItem; if more than one producer supplied a default route the aggregation fails with BuildException. The comment notes 'this should never happen' — it is an invariant check that multiple extensions/processors tried to define the default route. Only the first would be honored otherwise, silently masking a conflict.

Source

Thrown at extensions/vertx-http/deployment/src/main/java/io/quarkus/vertx/http/deployment/VertxHttpProcessor.java:468

            VertxHttpBuildTimeConfig httpBuildTimeConfig,
            List<RequireBodyHandlerBuildItem> requireBodyHandlerBuildItems,
            BodyHandlerBuildItem bodyHandlerBuildItem,
            List<ErrorPageActionsBuildItem> errorPageActionsBuildItems,
            BuildProducer<ShutdownListenerBuildItem> shutdownListenerBuildItemBuildProducer,
            LiveReloadConfig lrc,
            CoreVertxBuildItem core, // Injected to be sure that Vert.x has been produced before calling this method.
            ExecutorBuildItem executorBuildItem,
            TlsRegistryBuildItem tlsRegistryBuildItem, // Injected to be sure that the TLS registry has been produced before calling this method.
            Optional<VertxDevUILogBuildItem> vertxDevUILogBuildItem)
            throws BuildException {

        Optional<DefaultRouteBuildItem> defaultRoute;
        if (defaultRoutes == null || defaultRoutes.isEmpty()) {
            defaultRoute = Optional.empty();
        } else {
            if (defaultRoutes.size() > 1) {
                // this should never happen
                throw new BuildException("Too many default routes.", Collections.emptyList());
            } else {
                defaultRoute = Optional.of(defaultRoutes.get(0));
            }
        }

        GracefulShutdownFilter gracefulShutdownFilter = recorder.createGracefulShutdownHandler();
        shutdownListenerBuildItemBuildProducer.produce(new ShutdownListenerBuildItem(gracefulShutdownFilter));

        List<Filter> listOfFilters = filters.stream()
                .filter(f -> f.getHandler() != null)
                .map(FilterBuildItem::toFilter).collect(Collectors.toList());

        List<Filter> listOfManagementInterfaceFilters = managementInterfacefilters.stream()
                .filter(f -> f.getHandler() != null)
                .map(ManagementInterfaceFilterBuildItem::toFilter).collect(Collectors.toList());

        Optional<RuntimeValue<Router>> mainRouter = httpRouteRouter.getMainRouter() != null
                ? Optional.of(httpRouteRouter.getMainRouter())

View on GitHub (pinned to e1c734241f)

Solutions

  1. Remove your custom DefaultRouteBuildItem producer or the conflicting extension's one — exactly one may exist
  2. Use an @Recorder/@BuildStep combination guarded by a capability or config condition so only one default route is produced in a given app
  3. Search the build for 'DefaultRouteBuildItem' producers to identify the two conflicting sources

Example fix

// before (app producer conflicting with framework)
@BuildStep DefaultRouteBuildItem mine() { return new DefaultRouteBuildItem("/app"); }
// after — delete the producer, or gate it:
@BuildStep(onlyIfNot = DefaultRouteProvided.class) DefaultRouteBuildItem mine() { ... }
Defensive patterns

Strategy: validation

Validate before calling

long producers = buildSteps.stream()
    .filter(s -> s.produces(DefaultRouteBuildItem.class).count() > 0)
    .count();
if (producers > 1) {
    throw new IllegalStateException("multiple DefaultRouteBuildItem producers");
}

Try / catch

try {
    finalizeRouter(...);
} catch (BuildException e) {
    if (e.getMessage().contains("Too many default routes")) {
        // locate duplicate DefaultRouteBuildItem producers and remove one
    }
    throw e;
}

Prevention

When it happens

Trigger: Two or more @BuildStep methods producing DefaultRouteBuildItem in the same application, e.g. an extension and application code both producing a default route, leading defaultRoutes.size() > 1 in finalizeRouter.

Common situations: Adding a custom DefaultRouteBuildItem producer while another extension (or quarkus-vertx-http itself) already defines one; duplicated build-step logic after merging extensions.

Related errors


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