redis/jedis · error · IllegalArgumentException

protocol must not be null

Error message

protocol must not be null

What it means

ProtocolHandshake.enforceProtocolWithAuth() performs the HELLO-based protocol negotiation and authentication; it requires a concrete RedisProtocol and throws IllegalArgumentException "protocol must not be null" when it is null. This is an internal guard reached when a null protocol leaks through establish() or negotiateResp3WithFallback().

Solutions

  1. Set an explicit protocol (RedisProtocol.RESP2 or RESP3) in JedisClientConfig.
  2. If you call enforceProtocolWithAuth or negotiateResp3WithFallback directly, null-check the protocol first.
  3. Update/align Jedis versions so default protocol resolution is applied upstream.

Example fix

// before
connection.hello(null, credentials); // null protocol

// after
RedisProtocol protocol = config.getProtocol() != null ? config.getProtocol() : RedisProtocol.RESP3;
connection.hello(protocol, credentials);
Defensive patterns

Strategy: validation

Validate before calling

RedisProtocol proto = config.getProtocol();
if (proto == null) {
  proto = RedisProtocol.RESP3; // or RESP2 for pre-6.0 servers
}
handshake.enforceProtocolWithAuth(proto, credentials);

Prevention

When it happens

Trigger: Calling code that resolves the target protocol to null before handshake — e.g. a custom client/handshake entry passing DefaultJedisClientConfig.getProtocol() when it was never set and the default resolution returned null.

Common situations: Custom client builds overriding handshake logic, config builders missing the protocol field, or library/version mismatches where defaults changed.

Related errors


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

Appendix: source

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

   * </p>
   * <ul>
   * <li>Some Redis 6.0.x versions require authentication before allowing {@code HELLO}, even though
   * {@code HELLO AUTH} is supported in later versions.</li>
   * <li>This method assumes the server supports the requested protocol; unsupported protocol errors
   * are not handled and will be propagated.</li>
   * </ul>
   * @param protocol the RESP protocol version to negotiate (must not be {@code null})
   * @param credentials credentials used for authentication if required (may be {@code null})
   * @return the {@code HELLO} response containing negotiated protocol and server metadata
   * @throws IllegalArgumentException if {@code protocol} is {@code null}
   * @throws JedisProtocolNotSupportedException if the server does not support the requested
   *           protocol
   * @throws JedisAccessControlException if authentication fails and cannot be recovered
   */
  private HelloResult enforceProtocolWithAuth(RedisProtocol protocol,
      RedisCredentials credentials) {
    if (protocol == null) {
      throw new IllegalArgumentException("protocol must not be null");
    }

    try {
      try {
        return connection.hello(protocol, credentials);
      } catch (JedisDataException e) {
        if (isUnknownCommandError(e)) {
          throw new JedisProtocolNotSupportedException("Server does not support HELLO", e);
        } else {
          throw e;
        }
      }
    } catch (JedisAccessControlException e) {
      // Redis 6.0.x (before 6.2.2) has a bug where HELLO with AUTH fails if the default user
      // requires authentication — the server demands AUTH before allowing HELLO.
      // See: https://github.com/redis/redis/issues/8558
      // See: https://github.com/redis/lettuce/issues/2592
      if (isNoAuthError(e)) {

View on GitHub (pinned to 6dac31d4c2)