redisson/redisson · error · RedisSubscribedConnectionException

Connection already subscribed

Error message

Connection already subscribed

What it means

Redisson's RedissonConnection keeps at most one active RedisSubscription per connection. subscribe(MessageListener, byte[]...) calls checkSubscription(), which throws RedisSubscribedConnectionException when the subscription field is already non-null. This mirrors Redis semantics where a connection entering subscribe mode is dedicated to pub/sub and cannot start a second subscription.

Source

Thrown at redisson-spring/redisson-spring-data/redisson-spring-data-22/src/main/java/org/redisson/spring/data/connection/RedissonConnection.java:1635

        return subscription;
    }

    @Override
    public Long publish(byte[] channel, byte[] message) {
        return write(channel, StringCodec.INSTANCE, RedisCommands.PUBLISH, channel, message);
    }

    @Override
    public void subscribe(MessageListener listener, byte[]... channels) {
        checkSubscription();
        
        subscription = new RedissonSubscription(executorService, listener);
        subscription.subscribe(channels);
    }

    private void checkSubscription() {
        if (subscription != null) {
            throw new RedisSubscribedConnectionException("Connection already subscribed");
        }
        
        if (isQueueing()) {
            throw new UnsupportedOperationException("Not supported in queueing mode");
        }
        if (isPipelined()) {
            throw new UnsupportedOperationException("Not supported in pipelined mode");
        }
    }

    @Override
    public void pSubscribe(MessageListener listener, byte[]... patterns) {
        checkSubscription();
        
        subscription = new RedissonSubscription(executorService, listener);
        subscription.pSubscribe(patterns);
    }

View on GitHub (pinned to 91188987c2)

Solutions

  1. Use a fresh connection (RedisConnectionFactory.getConnection()) for each independent subscription instead of reusing the subscribed one.
  2. Unsubscribe and release the existing subscription before subscribing again on the same connection.
  3. Let Spring Data Redis' RedisMessageListenerContainer manage subscriptions — it dispatches each listener over dedicated connections.
  4. Wrap subscribe() in try-catch for RedisSubscribedConnectionException if accidental reuse is possible.

Example fix

// before
RedisConnection conn = factory.getConnection();
conn.subscribe(listenerA, "ch1".getBytes());
conn.subscribe(listenerB, "ch2".getBytes()); // throws

// after
RedisConnection connA = factory.getConnection();
connA.subscribe(listenerA, "ch1".getBytes());
RedisConnection connB = factory.getConnection();
connB.subscribe(listenerB, "ch2".getBytes());
Defensive patterns

Strategy: validation

Validate before calling

// Spring Data Redis does not expose isSubscribed(); track subscriptions yourself or
// rely on RedisMessageListenerContainer. If managing manually, keep one connection per subscription:
Map<MessageListener, RedisConnection> active = new ConcurrentHashMap<>();
RedisConnection conn = active.computeIfAbsent(listener, k -> factory.getConnection());

Try / catch

try {
    conn.subscribe(listener, channel);
} catch (RedisSubscribedConnectionException e) {
    // connection already dedicated to pub/sub: open a new one
    RedisConnection fresh = factory.getConnection();
    fresh.subscribe(listener, channel);
}

Prevention

When it happens

Trigger: Calling subscribe() (or pSubscribe(), which shares checkSubscription()) twice on the same RedissonConnection without closing/unsubscribing the first subscription; e.g. two listeners registered through the same RedisTemplate bound to one connection.

Common situations: Registering multiple MessageListener beans through a single RedisConnection; re-subscribing after a reconnect handler runs on the same connection; integration tests that reuse a connection across test cases without unsubscribing.

Related errors


AI-assisted analysis of redisson/redisson@91188987c2 (2026-08-14). Data as JSON: /api/errors/d14fdeb920a331b3. Report an issue: GitHub.