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
- Set the protocol explicitly to RedisProtocol.RESP2 or RedisProtocol.RESP3.
- Omit the protocol setting to use the library default.
- Fix the string-to-enum mapping in your config loader.
- 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
- Only reference the RedisProtocol enum constants shipped by your Jedis version.
- Guard string-to-enum config parsing with a whitelist (RESP2/RESP3).
- Let the library default the protocol unless you specifically need RESP2/RESP3.
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
- protocol must not be null
- Jedis does not support RESP3 protocol auto-negotiation…
- HELLO response is missing the protocol version field
- Blocking pub/sub operations are not supported on…
- Maintenance notifications:
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)