redis/jedis · error · IllegalArgumentException
protocol must not be null
Error message
protocol must not be null
What it means
Connection.hello() throws IllegalArgumentException when the RedisProtocol argument is null. The HELLO command requires a protocol version (RESP2 or RESP3), so the client refuses to send a HELLO without knowing which version to negotiate.
Solutions
- Pass an explicit RedisProtocol.RESP2 or RedisProtocol.RESP3 to hello()
- Set the protocol in DefaultJedisClientConfig via .protocol(RedisProtocol.RESP3) before building the connection
- If the server version is unknown, default to RESP2 (available since Redis 6) instead of null
Example fix
// before HelloResult r = connection.hello(null, creds); // after HelloResult r = connection.hello(RedisProtocol.RESP3, creds);
Defensive patterns
Strategy: validation
Validate before calling
if (protocol == null) {
throw new IllegalArgumentException("protocol must be RESP2 or RESP3 before calling hello()");
}
HelloResult r = connection.hello(protocol, creds); Type guard
boolean isValidProtocol(RedisProtocol p) { return p == RedisProtocol.RESP2 || p == RedisProtocol.RESP3; } Try / catch
try {
connection.hello(protocol, creds);
} catch (IllegalArgumentException e) {
// protocol was null; set a default and retry
} Prevention
- Always set .protocol(RedisProtocol.RESP3) in DefaultJedisClientConfig when using HELLO-based auth
- Never pass config-derived protocol values straight into hello() without a null check
- Default to RESP2 when the server version is unknown
When it happens
Trigger: Calling connection.hello(null, credentials) or hello(null, null) directly; passing a null RedisProtocol when building a Connection or performing handshake/auth that delegates to hello.
Common situations: Custom connection or provider code that resolves the protocol from a config object which was left unset (DefaultJedisClientConfig without a protocol); hand-rolled authentication flows calling the low-level hello API; refactors that made protocol resolution return null on older servers.
Related errors
- ${status}
- HostAndPort is required when no socketFactory is provided
- Failed to evict connections from pool
- DIALECT=0 cannot be set.
- Provided endpoint is null. Please use one from the…
AI-assisted analysis of redis/jedis@6dac31d4c2 (2026-09-08).
Data as JSON: /api/errors/694e7b9868ef5929.
Report an issue: GitHub.
Appendix: source
Thrown at src/main/java/redis/clients/jedis/Connection.java:1071
* <li>If {@code credentials} is provided but the password is {@code null}, no authentication
* is performed.</li>
* </ul>
*
* <p>Note:</p>
* <ul>
* <li>{@code HELLO} is available only in Redis 6.0 and newer.</li>
* <li>The command both negotiates the protocol version (RESP2/RESP3) and returns
* server metadata.</li>
* </ul>
*
* @param protocol the requested RESP protocol version (must not be {@code null})
* @param credentials optional credentials used for authentication (may be {@code null})
* @return the parsed {@code HELLO} response containing server metadata
* @throws IllegalArgumentException if {@code protocol} is {@code null}
*/
HelloResult hello(RedisProtocol protocol, RedisCredentials credentials) {
if (protocol == null) {
throw new IllegalArgumentException("protocol must not be null");
}
byte[] rawPass = null;
try {
byte[][] args;
byte[] versionRaw = encode(protocol.version());
if (credentials != null && credentials.getPassword() != null) {
String user = credentials.getUser();
if (user == null) {
user = "default";
}
rawPass = encodeToBytes(credentials.getPassword());
args = new byte[][] { versionRaw, Keyword.AUTH.getRaw(), encode(user), rawPass };
} else {
args = new byte[][] { versionRaw };
}
return new HelloResult(hello(args));
} finally {View on GitHub (pinned to 6dac31d4c2)