quarkusio/quarkus · error · IllegalArgumentException
@ExactlyOnce on method ${methodName}: outgoing channel '${ou
Error message
@ExactlyOnce on method ${methodName}: outgoing channel '${outgoingChannel}' is not managed by the Kafka connector What it means
Exactly-once processing requires the produced record to be sent within the same Kafka transaction as the offset commit, which is only possible when the outgoing channel uses the Kafka connector. This build-time error reports that the @Outgoing channel is not Kafka-connector-managed.
Source
Thrown at extensions/smallrye-reactive-messaging-kafka/deployment/src/main/java/io/quarkus/smallrye/reactivemessaging/kafka/deployment/SmallRyeReactiveMessagingKafkaProcessor.java:223
boolean isSuspend = method.parameterTypes().stream()
.anyMatch(t -> t.name().equals(DotNames.CONTINUATION));
if (isSuspend) {
throw new IllegalArgumentException(
"@ExactlyOnce on method " + methodName
+ " does not support Kotlin suspend functions");
}
String incomingChannel = incoming.value().asString();
String outgoingChannel = outgoing.value().asString();
if (!discoveryState.isKafkaConnector(channelsManagedByConnectors, true, incomingChannel)) {
throw new IllegalArgumentException(
"@ExactlyOnce on method " + methodName
+ ": incoming channel '" + incomingChannel + "' is not managed by the Kafka connector");
}
if (!discoveryState.isKafkaConnector(channelsManagedByConnectors, false, outgoingChannel)) {
throw new IllegalArgumentException(
"@ExactlyOnce on method " + methodName
+ ": outgoing channel '" + outgoingChannel + "' is not managed by the Kafka connector");
}
LOGGER.infof("Exactly-once processing detected on method %s#%s, " +
"configuring channels '%s' (incoming) and '%s' (outgoing)",
method.declaringClass().name(), method.name(), incomingChannel, outgoingChannel);
// Auto-configure outgoing channel for transactions
produceRuntimeConfigurationDefaultBuildItem(discoveryState, defaultConfigProducer,
getChannelOutgoingPropertyName(outgoingChannel, "transactional.id"),
"${quarkus.application.name}-" + outgoingChannel);
produceRuntimeConfigurationDefaultBuildItem(discoveryState, defaultConfigProducer,
getChannelOutgoingPropertyName(outgoingChannel, "enable.idempotence"), "true");
produceRuntimeConfigurationDefaultBuildItem(discoveryState, defaultConfigProducer,
getChannelOutgoingPropertyName(outgoingChannel, "acks"), "all");
// Auto-configure incoming channel for exactly-onceView on GitHub (pinned to e1c734241f)
Solutions
- Set mp.messaging.outgoing.<channel>.connector=smallrye-kafka with proper topic/acks settings.
- Fix the channel name in @Outgoing to match the Kafka-configured channel.
- Remove @ExactlyOnce if the pipeline is not fully Kafka-based.
Example fix
// before mp.messaging.outgoing.out.connector=smallrye-in-memory // after mp.messaging.outgoing.out.connector=smallrye-kafka mp.messaging.outgoing.out.topic=out-topic
Defensive patterns
Strategy: validation
Validate before calling
String connector = config.getValue("mp.messaging.outgoing." + channel + ".connector", String.class);
if (!"smallrye-kafka".equals(connector)) {
throw new IllegalStateException("outgoing channel must use smallrye-kafka for @ExactlyOnce");
} Prevention
- Set mp.messaging.outgoing.<ch>.connector=smallrye-kafka for exactly-once pipelines
- Never mix non-Kafka outgoing channels with @ExactlyOnce
- Keep both ends of the pipeline explicitly configured
When it happens
Trigger: The @Outgoing channel name fails discoveryState.isKafkaConnector(channelsManagedByConnectors, false, channel) — e.g. configured for another connector or an in-memory emitter.
Common situations: Producing to an in-memory channel or AMQP/Pulsar outgoing channel while the incoming is Kafka, or a missing/incorrect connector property for the outgoing channel.
Related errors
- @ExactlyOnce on method ${methodName}: incoming channel '${in
- @ExactlyOnce on method ${methodName} requires both @Incoming
- @ExactlyOnce on method ${methodName} must return a value to
- @ExactlyOnce on method ${methodName} cannot be combined with
- @ExactlyOnce on method ${methodName} cannot combine @WithTra
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/f235cfac9a2ff81f.
Report an issue: GitHub.