{"record":{"id":"3722bd119d3f9404","repo":"redis/jedis","slug":"protocol-must-not-be-null-3722bd","errorCode":null,"errorMessage":"protocol must not be null","messagePattern":"protocol must not be null","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/ProtocolHandshake.java","lineNumber":137,"sourceCode":"   * </p>\n   * <ul>\n   * <li>Some Redis 6.0.x versions require authentication before allowing {@code HELLO}, even though\n   * {@code HELLO AUTH} is supported in later versions.</li>\n   * <li>This method assumes the server supports the requested protocol; unsupported protocol errors\n   * are not handled and will be propagated.</li>\n   * </ul>\n   * @param protocol the RESP protocol version to negotiate (must not be {@code null})\n   * @param credentials credentials used for authentication if required (may be {@code null})\n   * @return the {@code HELLO} response containing negotiated protocol and server metadata\n   * @throws IllegalArgumentException if {@code protocol} is {@code null}\n   * @throws JedisProtocolNotSupportedException if the server does not support the requested\n   *           protocol\n   * @throws JedisAccessControlException if authentication fails and cannot be recovered\n   */\n  private HelloResult enforceProtocolWithAuth(RedisProtocol protocol,\n      RedisCredentials credentials) {\n    if (protocol == null) {\n      throw new IllegalArgumentException(\"protocol must not be null\");\n    }\n\n    try {\n      try {\n        return connection.hello(protocol, credentials);\n      } catch (JedisDataException e) {\n        if (isUnknownCommandError(e)) {\n          throw new JedisProtocolNotSupportedException(\"Server does not support HELLO\", e);\n        } else {\n          throw e;\n        }\n      }\n    } catch (JedisAccessControlException e) {\n      // Redis 6.0.x (before 6.2.2) has a bug where HELLO with AUTH fails if the default user\n      // requires authentication — the server demands AUTH before allowing HELLO.\n      // See: https://github.com/redis/redis/issues/8558\n      // See: https://github.com/redis/lettuce/issues/2592\n      if (isNoAuthError(e)) {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/ProtocolHandshake.java#L119-L155","documentation":"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().","triggerScenarios":"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.","commonSituations":"Custom client builds overriding handshake logic, config builders missing the protocol field, or library/version mismatches where defaults changed.","solutions":["Set an explicit protocol (RedisProtocol.RESP2 or RESP3) in JedisClientConfig.","If you call enforceProtocolWithAuth or negotiateResp3WithFallback directly, null-check the protocol first.","Update/align Jedis versions so default protocol resolution is applied upstream."],"exampleFix":"// before\nconnection.hello(null, credentials); // null protocol\n\n// after\nRedisProtocol protocol = config.getProtocol() != null ? config.getProtocol() : RedisProtocol.RESP3;\nconnection.hello(protocol, credentials);","handlingStrategy":"validation","validationCode":"RedisProtocol proto = config.getProtocol();\nif (proto == null) {\n  proto = RedisProtocol.RESP3; // or RESP2 for pre-6.0 servers\n}\nhandshake.enforceProtocolWithAuth(proto, credentials);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always set an explicit protocol in JedisClientConfig for custom handshake paths.","Null-check protocol before any hello()/handshake call.","Prefer the built-in establish()/client builders over calling handshake internals directly."],"tags":["configuration","null-check","handshake","protocol"],"backgroundTag":"null-argument","analyzedSha":"6dac31d4c224fb3257c216f3985340c6f500cdcb","analyzedAt":"2026-09-08T04:55:01.204Z","contentChangedAt":"2026-09-08T04:55:01.204Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}