quarkusio/quarkus · error · IllegalArgumentException

Channel must not be null

Error message

Channel must not be null

What it means

validateChannels() pre-checks the channel list for plain (non-pattern) subscriptions. A null channel element is invalid for Redis SUBSCRIBE, so an IllegalArgumentException is thrown before contacting the server. The list itself must also be non-null/non-empty (notNullOrEmpty check).

Source

Thrown at extensions/redis-client/runtime/src/main/java/io/quarkus/redis/runtime/datasource/ReactivePubSubCommandsImpl.java:163

            Consumer<Throwable> onException) {
        validatePatterns(patterns);
        nonNull(onMessage, "onMessage");

        return RedisConnections.withNewLongLivedConnection(client, conn -> {
            RedisAPI api = RedisAPI.api(conn);
            ReactiveRedisPatternSubscriberImpl subscriber = new ReactiveRedisPatternSubscriberImpl(conn, api, patterns,
                    onMessage, onEnd, onException);
            return subscriber.subscribe()
                    .replaceWith(subscriber);
        });
    }

    private void validateChannels(List<String> channels) {
        notNullOrEmpty(channels, "channels");

        for (String pattern : channels) {
            if (pattern == null) {
                throw new IllegalArgumentException("Channel must not be null");
            }
            if (pattern.isBlank()) {
                throw new IllegalArgumentException("Channel cannot be blank");
            }
        }
    }

    @Override
    public Uni<ReactiveRedisSubscriber> subscribe(List<String> channels, Consumer<V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        nonNull(onMessage, "onMessage");
        validateChannels(channels);

        return RedisConnections.withNewLongLivedConnection(client, conn -> {
            RedisAPI api = RedisAPI.api(conn);
            ReactiveAbstractRedisSubscriberImpl subscriber = new ReactiveAbstractRedisSubscriberImpl(conn, api,
                    channels, (channel, value) -> onMessage.accept(value), onEnd, onException);
            return subscriber.subscribe()

View on GitHub (pinned to e1c734241f)

Solutions

  1. Filter null (and blank) entries before subscribing: channels.stream().filter(Objects::nonNull).toList().
  2. Validate channel names when assembling the subscription list.
  3. Ensure the channel list is non-empty; skip subscription entirely if there is nothing to subscribe to.

Example fix

// before
subscriber = pubsub.subscribe(channels, onMessage);

// after
List<String> safe = channels.stream().filter(c -> c != null && !c.isBlank()).toList();
subscriber = pubsub.subscribe(safe, onMessage);
Defensive patterns

Strategy: validation

Validate before calling

if (channels == null || channels.isEmpty() || channels.stream().anyMatch(Objects::isNull)) {
    throw new IllegalArgumentException("channels must be non-empty with no null elements");
}

Try / catch

try {
    pubsub.subscribe(channels, onMessage);
} catch (IllegalArgumentException e) {
    // sanitize channel list and retry
}

Prevention

When it happens

Trigger: Calling subscribe(...) with a List<String> of channels containing a null element.

Common situations: Channel names built from nullable variables or optional config values; collecting channels from a map/collection that permits null values.

Related errors


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