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
- Ensure a non-null MultiSubscriber is passed; construct a default/logging subscriber when none is available.
- Check the upstream caller that produced a null subscriber (uninitialized field, failed injection) and fix its initialization.
- 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
- Prefer Mutiny's subscribe().with(consumer) APIs, which never accept null subscribers silently.
- Initialize subscriber fields eagerly; make resolveSubscriber() return a default instead of null.
- Follow reactive-streams spec rule 2.13 in any custom reactive adapter code.
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
- Mapper returned null
- Demand must be greater than zero
- service interface descriptor file path cannot be null
- Cannot attach headers to a null client
- Compression cannot be null
AI-assisted analysis of quarkusio/quarkus@e1c734241f (2026-09-05).
Data as JSON: /api/errors/e8f59f86f1fffcba.
Report an issue: GitHub.