quarkusio/quarkus · error · IllegalStateException
The execution model %s of %s is not supported
Error message
The execution model %s of %s is not supported
What it means
DefaultBlockingReceiverExecutor only runs receivers whose execution model it supports (blocking models). At runtime, execute() checks the receiver's execution model and throws IllegalStateException if it cannot run it — the build-time check (error 2111) was bypassed, e.g. by a custom Receiver registered programmatically.
Source
Thrown at extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/DefaultBlockingReceiverExecutor.java:40
private final ConcurrencyLimiter blockingLimiter;
DefaultBlockingReceiverExecutor(ExecutorService executorService, SignalsRuntimeConfig config) {
this.executorService = executorService;
int limit = config.receivers().blockingConcurrencyLimit().orElse(-1);
this.blockingLimiter = limit > 0 ? new ConcurrencyLimiter(limit) : null;
}
@Override
public boolean supportsExecutionModel(ExecutionModel val) {
return val == ExecutionModel.BLOCKING;
}
@Override
public <SIGNAL, RESPONSE> Uni<RESPONSE> execute(Receiver<SIGNAL, RESPONSE> receiver, SignalContext<SIGNAL> context) {
ExecutionModel executionModel = receiver.executionModel();
if (!supportsExecutionModel(executionModel)) {
throw new IllegalStateException(
"The execution model %s of %s is not supported".formatted(executionModel, receiver));
}
LOG.debugf("Notify %s [signal=%s, emission=%s]", receiver, context.signalType(),
context.emissionType());
CompletableFuture<RESPONSE> ret = execute(executionModel, new Callable<Uni<RESPONSE>>() {
@Override
public Uni<RESPONSE> call() throws Exception {
return receiver.notify(context);
}
});
return Uni.createFrom().completionStage(ret);
}
protected <RESULT> CompletableFuture<RESULT> execute(ExecutionModel executionModel, Callable<Uni<RESULT>> action) {
CompletableFuture<RESULT> ret = new CompletableFuture<>();
ConcurrencyLimiter limiter = blockingLimiter;
if (limiter != null) {
limiter.run(new Runnable() {View on GitHub (pinned to e1c734241f)
Solutions
- Change the receiver to a blocking signature/model supported by the default executor.
- Register/configure an executor implementation that supports the receiver's execution model.
- Verify custom receivers are validated with supportsExecutionModel() before wiring them.
Example fix
// before
receivers.register(new Receiver<>() {
public Uni<Response> onSignal(Signal s) { ... }
});
// after (blocking executor)
receivers.register(new Receiver<>() {
public Response onSignal(Signal s) { ... }
}); Defensive patterns
Strategy: try-catch
Validate before calling
// Before wiring a custom receiver:
if (!executor.supportsExecutionModel(receiver.executionModel())) { throw new IllegalArgumentException("executor cannot run " + receiver); } Try / catch
try {
executor.execute(receiver, ctx).await().indefinitely();
} catch (IllegalStateException e) {
if (e.getMessage().contains("execution model")) { log.fatal("receiver executor/model mismatch"); throw e; }
throw e;
} Prevention
- Keep custom receivers blocking when using DefaultBlockingReceiverExecutor.
- Call supportsExecutionModel() when registering receivers programmatically.
- Avoid mixing reactive receiver signatures with blocking executors.
When it happens
Trigger: Calling execute() on a receiver whose Receiver.executionModel() is a non-blocking/reactive model while using DefaultBlockingReceiverExecutor, typically via a programmatically registered receiver.
Common situations: Registering a custom receiver through Receivers API with an async signature but the default (blocking) executor selected, or config switching executors after receivers were written reactively.
Related errors
- %s execution model is not supported: %s
- No datasource named '<dataSourceName>' exists
- Not implemented yet
- Proxy configuration with name ${key} was requested but quark
- Cannot cache `null` value
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/5272c795c2ac3417.
Report an issue: GitHub.