redis/jedis · error · IllegalArgumentException

Unsupported protocol:

Error message

Unsupported protocol: 

What it means

ProtocolHandshake.establish() switches on the requested RedisProtocol and only knows RESP2 and RESP3. Any other value (null, a future/unknown protocol enum value) is rejected with IllegalArgumentException "Unsupported protocol: X" before the HELLO handshake is attempted.

Solutions

  1. Set the protocol explicitly to RedisProtocol.RESP2 or RedisProtocol.RESP3.
  2. Omit the protocol setting to use the library default.
  3. Fix the string-to-enum mapping in your config loader.
  4. Align Jedis versions so only known RedisProtocol values are referenced.

Example fix

// before
JedisClientConfig config = DefaultJedisClientConfig.builder()
    .protocol(parseProtocol(cfg.get("redis.protocol"))) // returns null -> throws
    .build();

// after
RedisProtocol proto = parseProtocol(cfg.get("redis.protocol"));
JedisClientConfig config = DefaultJedisClientConfig.builder()
    .protocol(proto == null ? RedisProtocol.RESP3 : proto)
    .build();
Defensive patterns

Strategy: validation

Validate before calling

RedisProtocol proto = config.getProtocol();
if (proto != RedisProtocol.RESP2 && proto != RedisProtocol.RESP3) {
  throw new IllegalArgumentException("protocol must be RESP2 or RESP3, got: " + proto);
}

Prevention

When it happens

Trigger: Building a client (JedisClientConfig) with a RedisProtocol value other than RedisProtocol.RESP2 or RESP3 — typically null parsed from config or an unhandled enum constant from a newer Jedis/other library.

Common situations: Protocol version read from external config (string mapped incorrectly to enum), copy-paste of protocol constants from another library, or upgrades where a new enum value meets an old jar.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/ProtocolHandshake.java:73

   * @throws JedisDataException if the server returns an error during handshake
   */
  HelloResult establish(final RedisProtocol requestedProtocol, final boolean autoNegotiateProtocol,
      final RedisCredentials credentials) {
    if (requestedProtocol == null) {
      if (autoNegotiateProtocol) {
        return negotiateResp3WithFallback(credentials);
      }
      // Legacy compatibility: skip HELLO entirely, only authenticate if credentials are provided.
      // Connection assumes RESP2 on the wire.
      connection.authenticate(credentials);
      return new HelloResult(
          Collections.singletonMap("proto", Long.valueOf(RedisProtocol.RESP2.version())));
    } else if (requestedProtocol == RedisProtocol.RESP2) {
      return enforceProtocolWithAuth(RedisProtocol.RESP2, credentials);
    } else if (requestedProtocol == RedisProtocol.RESP3) {
      return enforceProtocolWithAuth(RedisProtocol.RESP3, credentials);
    } else {
      throw new IllegalArgumentException("Unsupported protocol: " + requestedProtocol);
    }
  }

  /**
   * Send HELLO command to the server to negotiate the protocol version and authenticate if needed.
   * <p>
   * Attempts RESP3 handshake, falls back to RESP2 if not supported.
   * </p>
   * @param credentials credentials for authentication
   * @return {@link HelloResult} the actual negotiated protocol version
   */
  private HelloResult negotiateResp3WithFallback(final RedisCredentials credentials) {
    try {
      return enforceProtocolWithAuth(RedisProtocol.RESP3, credentials);
    } catch (JedisProtocolNotSupportedException e) {
      // fall back to resp2
      return establishLegacyResp2(credentials);
    } catch (JedisDataException e) {

View on GitHub (pinned to 6dac31d4c2)