quarkusio/quarkus · error · IllegalArgumentException

Pattern must not be null

Error message

Pattern must not be null

What it means

validatePatterns() pre-checks the list passed to pattern-based pub/sub subscriptions. A null element inside the patterns list is invalid because Redis PSUBSCRIBE requires literal glob patterns; the method throws IllegalArgumentException before any network call is made.

Source

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

    @Override
    public Uni<ReactiveRedisSubscriber> subscribeToPattern(String pattern, Consumer<V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        return subscribeToPatterns(List.of(pattern), onMessage, onEnd, onException);
    }

    @Override
    public Uni<ReactiveRedisSubscriber> subscribeToPattern(String pattern, BiConsumer<String, V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        return subscribeToPatterns(List.of(pattern), onMessage, onEnd, onException);
    }

    private void validatePatterns(List<String> patterns) {
        notNullOrEmpty(patterns, "patterns");

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

    @Override
    public Uni<ReactiveRedisSubscriber> subscribeToPatterns(List<String> patterns, Consumer<V> onMessage, Runnable onEnd,
            Consumer<Throwable> onException) {
        nonNull(onMessage, "onMessage");
        validatePatterns(patterns);

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

View on GitHub (pinned to e1c734241f)

Solutions

  1. Filter or reject null entries before subscribing: patterns.stream().filter(Objects::nonNull).toList().
  2. Validate subscription patterns at configuration/initialization time.
  3. Use explicit defaults (e.g. "*") when a pattern is absent.

Example fix

// before
subscriber = pubsub.subscribeToPatterns(patterns, onMessage);

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

Strategy: validation

Validate before calling

if (patterns == null || patterns.stream().anyMatch(Objects::isNull)) {
    throw new IllegalArgumentException("patterns must not contain null elements");
}

Try / catch

try {
    pubsub.subscribeToPatterns(patterns, onMessage);
} catch (IllegalArgumentException e) {
    // sanitize input and retry
}

Prevention

When it happens

Trigger: Calling subscribeToPatterns(...) with a List<String> that contains a null element (list itself is checked by notNullOrEmpty first).

Common situations: Building the pattern list dynamically from config or user input where a missing entry becomes null; mapping nullable config values into the subscription list.

Related errors


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