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
- Remove your custom DefaultRouteBuildItem producer or the conflicting extension's one — exactly one may exist
- Use an @Recorder/@BuildStep combination guarded by a capability or config condition so only one default route is produced in a given app
- 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
- Produce DefaultRouteBuildItem from at most one build step in an application
- Gate default-route producers behind capabilities or config conditions when writing shared extensions
- Grep the dependency tree/extension sources for DefaultRouteBuildItem producers before adding your own
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
- This method is not supported using this builder. Use #routeF
- Cannot display <routeFunction> on not found page as no expli
- 'RouteBuildItem$Builder.routeFunction' was not set. Ensure t
- Cannot discover value of <routeConfigKey> as no explicit pat
- Cannot display <routeFunction> on not found page as no expli
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/4bcddbec4a85d93c.
Report an issue: GitHub.