redis/jedis · error · JedisException

Blocking pub/sub operations are not supported on…

Error message

Blocking pub/sub operations are not supported on token-based authentication enabled connections with RESP2 protocol!

What it means

With RESP2 there is no push-type notification, so token-based (ACL credential/credential-provider) authentication that needs re-authentication via client tracking/refresh cannot run concurrently with blocking pub/sub reads; a blocked subscribe loop would prevent token renewal and the connection could be revoked mid-stream. Jedis deliberately rejects the combination: subscribe/psubscribe on a connection that both uses token-based authentication and negotiates RESP2 throws this JedisException from checkConnectionSuitableForPubSub (JedisPubSubBase.java:65).

Solutions

  1. Set protocol RESP3 in the client config: config.protocol(RedisProtocol.RESP3), which supports push messages alongside token auth.
  2. Disable token-based authentication on the subscribing connection (use static password) if RESP2 must be kept.
  3. Use a separate connection/client for pub/sub with non-token (static) credentials.

Example fix

// before
JedisClientConfig config = new DefaultJedisClientConfig.Builder()
    .credentialProvider(provider)
    .build(); // RESP2 default -> throws on subscribe

// after
JedisClientConfig config = new DefaultJedisClientConfig.Builder()
    .credentialProvider(provider)
    .protocol(RedisProtocol.RESP3)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

if (clientConfig.getCredentialProvider() != null
    && clientConfig.getRedisProtocol() != RedisProtocol.RESP3) {
  // switch to RESP3 or use static credentials before subscribing
}

Try / catch

try {
  pubSub.subscribe(jedis, channel);
} catch (JedisException e) {
  if (e.getMessage().contains("token-based authentication")) {
    jedis = openConnectionWithResp3(config.protocol(RedisProtocol.RESP3));
    pubSub.subscribe(jedis, channel);
  }
}

Prevention

When it happens

Trigger: Calling subscribe(), psubscribe() (or the lazySubscribe equivalents) on a connection whose JedisClientConfig enables token-based authentication (e.g. CredentialProvider with renewal) while the protocol is RESP2 (protocol default or explicitly set to ProtocolVersion.RESP2).

Common situations: Using Redis 6 ACL credentials with a credential provider on default RESP2 protocol; forgetting to set .protocol(RedisProtocol.RESP3) in the client config when token-based auth is on, then subscribing to channels.

Understand the failure class

Related errors


AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08). Data as JSON: /api/errors/a9ac67b6f7696535. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/redis/clients/jedis/JedisPubSubBase.java:65

  public final void unsubscribe(T... channels) {
    sendAndFlushCommand(Command.UNSUBSCRIBE, channels);
  }

  public final void subscribe(T... channels) {
    checkConnectionSuitableForPubSub();
    sendAndFlushCommand(Command.SUBSCRIBE, channels);
  }

  public final void psubscribe(T... patterns) {
    checkConnectionSuitableForPubSub();
    sendAndFlushCommand(Command.PSUBSCRIBE, patterns);
  }

  private void checkConnectionSuitableForPubSub() {
    if (authenticator.client.getRedisProtocol() != RedisProtocol.RESP3
        && authenticator.client.isTokenBasedAuthenticationEnabled()) {
      throw new JedisException(
          "Blocking pub/sub operations are not supported on token-based authentication enabled connections with RESP2 protocol!");
    }
  }

  public final void punsubscribe() {
    sendAndFlushCommand(Command.PUNSUBSCRIBE);
  }

  public final void punsubscribe(T... patterns) {
    sendAndFlushCommand(Command.PUNSUBSCRIBE, patterns);
  }

  public final void ping() {
    authenticator.commandSync.lock();
    try {
      sendAndFlushCommand(Command.PING);
      authenticator.resultHandler.add(pingResultHandler);
    } finally {

View on GitHub (pinned to 6dac31d4c2)