quarkusio/quarkus · error · IllegalStateException
An event consumer business method that accepts io.vertx.core
Error message
An event consumer business method that accepts io.vertx.core.eventbus.Message or io.vertx.mutiny.core.eventbus.Message must return void [method: %s, bean:%s]
What it means
When a @ConsumeEvent method consumes the full io.vertx.core.eventbus.Message (or Mutiny Message) instead of just the payload, Quarkus requires it to return void. Message-consuming methods handle replies themselves via message.reply(); a non-void return type is ambiguous and rejected at build time.
Source
Thrown at extensions/vertx/deployment/src/main/java/io/quarkus/vertx/deployment/VertxProcessor.java:190
if (parametersCount == 2) {
if (!isMessageHeaders(params.get(0).name())) {
// If there are two parameters, the first must be message headers.
throw new IllegalStateException(String.format(
"An event consumer business method with two parameters must have MultiMap as the first parameter: %s [method: %s, bean:%s]",
params, method, bean));
} else if (isMessage(params.get(1).name())) {
throw new IllegalStateException(String.format(
"An event consumer business method with two parameters must not accept io.vertx.core.eventbus.Message or io.vertx.mutiny.core.eventbus.Message: %s [method: %s, bean:%s]",
params, method, bean));
}
} else if (parametersCount != 1) {
throw new IllegalStateException(String.format(
"An event consumer business method must accept exactly one parameter: %s [method: %s, bean:%s]",
params, method, bean));
}
if (method.returnType().kind() != Kind.VOID && VertxConstants.isMessage(params.get(0).name())
&& !KotlinUtils.isKotlinSuspendMethod(method)) {
throw new IllegalStateException(String.format(
"An event consumer business method that accepts io.vertx.core.eventbus.Message or io.vertx.mutiny.core.eventbus.Message must return void [method: %s, bean:%s]",
method, bean));
}
if (method.hasAnnotation(RunOnVirtualThread.class) && consumeEvent.value("ordered") != null
&& consumeEvent.value("ordered").asBoolean()) {
throw new IllegalStateException(String.format(
"An event consumer business method that cannot use @RunOnVirtualThread and set the ordered attribute to true [method: %s, bean:%s]",
method, bean));
}
InvokerBuilder builder = invokerFactory.createInvoker(bean, method)
.withInstanceLookup();
if (parametersCount == 1 && method.parameterType(0).name().equals(MESSAGE)) {
// io.vertx.core.eventbus.Message
// no transformation required
} else if (parametersCount == 1 && method.parameterType(0).name().equals(MUTINY_MESSAGE)) {
// io.vertx.mutiny.core.eventbus.MessageView on GitHub (pinned to e1c734241f)
Solutions
- Make the method return void and reply explicitly with message.reply(...)/message.fail(...)
- If you want to return a value, consume the raw payload instead of Message and let the returned object be the reply
- Convert to Uni<Void>/CompletionStage<Void> only via a payload-style method if async processing is needed
- For Kotlin, keep the method suspend — it is allowed despite non-void semantics
Example fix
// before
@ConsumeEvent("greeting")
String consume(Message<String> msg) { return "hi"; }
// after
@ConsumeEvent("greeting")
void consume(Message<String> msg) { msg.reply("hi"); } Defensive patterns
Strategy: validation
Validate before calling
if ((param instanceof io.vertx.core.eventbus.Message
|| param instanceof io.vertx.mutiny.core.eventbus.Message)
&& method.getReturnType() != void.class) {
throw new IllegalStateException("Message-consuming @ConsumeEvent methods must return void: " + method);
} Prevention
- Return void when consuming Message; reply via msg.reply()/fail()
- Reserve return values for payload-style consumers
- Remember Kotlin suspend methods are exempt from this rule
- Grep for '@ConsumeEvent' methods returning non-void with Message params in CI
When it happens
Trigger: A @ConsumeEvent method whose sole parameter is Message/Mutiny Message and whose return type is not void (e.g. returns String, Uni, or a payload object). Kotlin suspend methods are exempt.
Common situations: Migrating a payload-style consumer to Message style but keeping the return value; copying a payload consumer signature and swapping the parameter to Message; auto-complete generating a reply-returning method.
Related errors
- An event consumer business method must accept exactly one pa
- An event consumer business method that cannot use @RunOnVirt
- Failed to find any non-blocking provider for startup actions
- Type ${className} must be annotated with @Embeddable, becaus
- No Vert.x instance has been registered in ArC ?
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/728c84eb19e22d4e.
Report an issue: GitHub.