quarkusio/quarkus · error · IllegalStateException

%s not supported by %s

Error message

%s not supported by %s

What it means

When a callback receiver is registered programmatically, ReceiverManager checks that the chosen executor supports the receiver's required execution model (e.g. blocking vs event-loop). If the executor cannot run that execution model, registration fails with an IllegalStateException stating which execution model is unsupported and by which executor class.

Source

Thrown at extensions/signals/runtime/src/main/java/io/quarkus/signals/runtime/impl/ReceiverManager.java:152

    @Override
    public List<ReceiverInfo> resolveReceivers(TypeLiteral<?> signalType, Annotation... qualifiers) {
        return cast(resolveReceivers(signalType.getType(), Set.of(qualifiers)));
    }

    @Override
    public <SIGNAL> ReceiverDefinition<SIGNAL> newReceiver(Class<SIGNAL> signalType) {
        return new ReceiverDefinitionImpl<>(signalType, beanContainer, this::register);
    }

    @Override
    public <SIGNAL> ReceiverDefinition<SIGNAL> newReceiver(TypeLiteral<SIGNAL> signalType) {
        return new ReceiverDefinitionImpl<>(signalType.getType(), beanContainer, this::register);
    }

    private Registration register(CallbackReceiver<?, ?> receiver) {
        if (!executor.supportsExecutionModel(receiver.executionModel())) {
            throw new IllegalStateException(
                    "%s not supported by %s".formatted(receiver.executionModel(), executor.getClass().getName()));
        }
        receivers.put(receiver.id(), wrapReceiver(receiver));
        invalidateCache(receiver);
        return new Registration() {
            @Override
            public void unregister() {
                receivers.remove(receiver.id());
                invalidateCache(receiver);
            }
        };
    }

    private Receiver<?, ?> wrapReceiver(Receiver<?, ?> receiver) {
        if (interceptors.isEmpty()) {
            return receiver;
        }
        return new InterceptedReceiver<>(receiver, interceptors);

View on GitHub (pinned to e1c734241f)

Solutions

  1. Change the receiver's declared execution model to one the executor supports (e.g. use a non-blocking/event-loop model)
  2. Configure or select an executor that supports the required execution model
  3. Register the receiver through supported configuration instead of manual registration if the model mismatch is unintentional

Example fix

// before
builder.withExecutionModel(ExecutionModel.BLOCKING);
// after
builder.withExecutionModel(ExecutionModel.EVENT_LOOP);
Defensive patterns

Strategy: validation

Validate before calling

if (!executor.supportsExecutionModel(model)) {
    throw new IllegalArgumentException(model + " unsupported by " + executor.getClass().getName());
}

Try / catch

try { definition.register(); }
catch (IllegalStateException e) { log.errorf("Receiver registration failed: %s", e.getMessage()); }

Prevention

When it happens

Trigger: Calling newReceiver(signalType) and completing the ReceiverDefinition with an execution model (from the CallbackReceiver) that the SignalExecutor used by the bean container does not support — e.g. registering a blocking receiver on an event-loop-only executor.

Common situations: Registering receivers manually in a @Startup bean and marking them as blocking while running on a Vert.x/event-loop executor; copying receiver registration code from an example using a different executor configuration.

Related errors


AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05). Data as JSON: /api/errors/325c13229100ac14. Report an issue: GitHub.