quarkusio/quarkus · error · java.lang.IllegalStateException
Route filter method must return void [method: %s, bean: %s]
Error message
Route filter method must return void [method: %s, bean: %s]
What it means
Route filter methods (@RouteFilter) must return void because they work by mutating the RoutingContext/continuing the chain, not by returning a value. validateRouteFilterMethod throws IllegalStateException during build if a filter method declares a non-void return type.
Source
Thrown at extensions/reactive-routes/deployment/src/main/java/io/quarkus/vertx/web/deployment/ReactiveRoutesProcessor.java:518
priorityValue != null ? priorityValue.asInt() : RouteFilter.DEFAULT_PRIORITY));
}
detectConflictingRoutes(matchers);
}
@BuildStep
AutoAddScopeBuildItem autoAddScope() {
return AutoAddScopeBuildItem.builder()
.containsAnnotations(DotNames.ROUTE,
DotNames.ROUTES,
DotNames.ROUTE_FILTER)
.defaultScope(BuiltinScope.SINGLETON)
.reason("Found route handler business methods").build();
}
private void validateRouteFilterMethod(BeanInfo bean, MethodInfo method) {
if (!method.returnType().kind().equals(Type.Kind.VOID)) {
throw new IllegalStateException(
String.format("Route filter method must return void [method: %s, bean: %s]", method, bean));
}
List<Type> params = method.parameterTypes();
if (params.size() != 1 || !params.get(0).name()
.equals(DotNames.ROUTING_CONTEXT)) {
throw new IllegalStateException(String.format(
"Route filter method must accept exactly one parameter of type %s: %s [method: %s, bean: %s]",
DotNames.ROUTING_CONTEXT, params, method, bean));
}
}
private void validateRouteMethod(BeanInfo bean, MethodInfo method,
TransformedAnnotationsBuildItem transformedAnnotations, IndexView index, AnnotationInstance routeAnnotation) {
List<Type> params = method.parameterTypes();
if (params.isEmpty()) {
if (method.returnType().kind() == Kind.VOID && params.isEmpty()) {
throw new IllegalStateException(String.format(
"Route method that returns void must accept at least one injectable parameter [method: %s, bean: %s]",View on GitHub (pinned to e1c734241f)
Solutions
- Change the @RouteFilter method return type to void
- If a value must be produced, store it in the RoutingContext via rc.put(...) instead of returning it
- Rename the method so IDE quick-fixes don't reintroduce a return type
Example fix
// before
@RouteFilter(100)
public String myFilter(RoutingContext rc) { ... }
// after
@RouteFilter(100)
public void myFilter(RoutingContext rc) { rc.next(); } Defensive patterns
Strategy: validation
Validate before calling
Method m = bean.getClass().getMethod("myFilter", RoutingContext.class);
if (m.isAnnotationPresent(RouteFilter.class)
&& m.getReturnType() != void.class) {
throw new IllegalStateException("@RouteFilter must return void");
} Type guard
boolean isValidRouteFilter(Method m) {
return m.getReturnType() == void.class
&& m.getParameterCount() == 1
&& m.getParameterTypes()[0] == RoutingContext.class;
} Prevention
- Always declare @RouteFilter methods as void
- Check route filter signature in code reviews
- Use a project template/snippet for filters
When it happens
Trigger: Annotating a @RouteFilter method that returns a value (e.g. String, Response, Uni) instead of void.
Common situations: Returning a value from a filter by habit from JAX-RS filters; converting an endpoint method into a filter while keeping its return type; forgetting to change the signature when adding @RouteFilter.
Related errors
- Route filter method must accept exactly one parameter of typ
- Unknown type
- Unsupported param type: " + paramType
- Failed to open path tree with root %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/50588f06ba72d500.
Report an issue: GitHub.