quarkusio/quarkus · error · NullPointerException

The subscriber must not be `null`

Error message

The subscriber must not be `null`

What it means

RestMulti implements MultiSubscriber semantics and follows the reactive-streams spec rule 2.13: subscribing with a null subscriber is a hard error. subscribe() throws NullPointerException when passed null, preventing NPEs deeper inside the reactive pipeline.

Source

Thrown at independent-projects/resteasy-reactive/common/runtime/src/main/java/org/jboss/resteasy/reactive/RestMulti.java:201

        private final AtomicReference<Map<String, List<String>>> headers;
        private final Uni<I> upstream;

        public <T> AsyncRestMulti(Uni<I> upstream,
                Function<? super I, ? extends Multi<? extends O>> dataExtractor,
                Function<I, Map<String, List<String>>> headersExtractor,
                Function<I, Integer> statusExtractor) {
            this.upstream = upstream;
            this.dataExtractor = dataExtractor;
            this.statusExtractor = statusExtractor;
            this.headersExtractor = headersExtractor;
            this.status = new AtomicReference<>(null);
            this.headers = new AtomicReference<>(Collections.emptyMap());
        }

        @Override
        public void subscribe(MultiSubscriber<? super O> subscriber) {
            if (subscriber == null) {
                throw new NullPointerException("The subscriber must not be `null`");
            }
            AbstractUni.subscribe(upstream, new FlatMapPublisherSubscriber<>(subscriber, dataExtractor, statusExtractor, status,
                    headersExtractor, headers));
        }

        @Override
        public Integer getStatus() {
            return status.get();
        }

        @Override
        public Map<String, List<String>> getHeaders() {
            return headers.get();
        }

        static final class FlatMapPublisherSubscriber<I, O>
                implements Flow.Subscriber<O>, UniSubscriber<I>, Flow.Subscription, ContextSupport {

View on GitHub (pinned to e1c734241f)

Solutions

  1. Ensure a non-null MultiSubscriber is passed; construct a default/logging subscriber when none is available.
  2. Check the upstream caller that produced a null subscriber (uninitialized field, failed injection) and fix its initialization.
  3. Let Mutiny's built-in subscription APIs (e.g. `multi.subscribe().with(...)` with non-null callbacks) handle subscription instead of calling subscribe(null) directly.

Example fix

// before
MultiSubscriber<? super Item> sub = resolveSubscriber(); // may be null
restMulti.subscribe(sub);
// after
MultiSubscriber<? super Item> sub = resolveSubscriber();
if (sub == null) {
    sub = new LoggingSubscriber<>();
}
restMulti.subscribe(sub);
Defensive patterns

Strategy: type-guard

Validate before calling

if (subscriber == null) {
    subscriber = new LoggingSubscriber<>();
}
restMulti.subscribe(subscriber);

Type guard

boolean hasSubscriber(MultiSubscriber<?> s) {
    return s != null;
}

Try / catch

try {
    restMulti.subscribe(subscriber);
} catch (NullPointerException e) {
    LOG.error("Attempted to subscribe with null subscriber", e);
}

Prevention

When it happens

Trigger: Calling `restMulti.subscribe(null)` directly, or framework plumbing (e.g. AbstractUni.subscribe wiring) passing a null subscriber because a downstream stage was never initialized.

Common situations: Custom integration code that resolves the subscriber from an optional context/parameter and passes the null result through; misordered initialization in custom reactive adapters.

Related errors


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