{"record":{"id":"830160866650ec11","repo":"redis/jedis","slug":"hello-response-is-missing-the-protocol-version-fie","errorCode":null,"errorMessage":"HELLO response is missing the protocol version field","messagePattern":"HELLO response is missing the protocol version field","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"critical","filePath":"src/main/java/redis/clients/jedis/Connection.java","lineNumber":1004,"sourceCode":"   *          {@code autoNegotiateProtocol}\n   * @param autoNegotiateProtocol whether to attempt {@code HELLO 3} with RESP2 fallback when no\n   *          protocol is explicitly requested; ignored when {@code requestedProtocol} is\n   *          non-{@code null}\n   * @param credentials credentials used for authentication (may be {@code null})\n   * @throws IllegalArgumentException if the requested protocol is not supported\n   * @throws IllegalStateException if the server's HELLO response is missing the protocol field\n   * @throws JedisProtocolNotSupportedException if protocol negotiation fails\n   * @throws JedisDataException if the server returns an error during handshake\n   */\n  private void establishProtocol(final RedisProtocol requestedProtocol,\n      final boolean autoNegotiateProtocol, final RedisCredentials credentials) {\n    HelloResult helloResult = handshake.establish(requestedProtocol, autoNegotiateProtocol,\n      credentials);\n    version = helloResult.getVersion();\n    server = helloResult.getServer();\n\n    if (helloResult.getProtocol() == null) {\n      throw new IllegalStateException(\"HELLO response is missing the protocol version field\");\n    }\n\n    this.protocol = helloResult.getProtocol();\n  }\n\n  public void setCredentials(RedisCredentials credentials) {\n    currentCredentials.set(credentials);\n  }\n\n  String authenticate(RedisCredentials credentials) {\n    if (credentials == null || credentials.getPassword() == null) {\n      return null;\n    }\n    byte[] rawPass = encodeToBytes(credentials.getPassword());\n    try {\n      if (credentials.getUser() == null) {\n        sendCommand(Command.AUTH, rawPass);\n      } else {","sourceCodeStart":986,"sourceCodeEnd":1022,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/Connection.java#L986-L1022","documentation":"After the HELLO handshake, Connection verifies that the server-reported HELLO map contained a protocol version field, from which the negotiated RedisProtocol is derived. A null protocol means the server's HELLO reply was malformed or unexpectedly shaped, so an IllegalStateException is thrown to prevent running with an unknown protocol.","triggerScenarios":"Connecting to an endpoint that returns an incomplete HELLO reply — e.g. a proxy/middleware (Envoy, Twemproxy-like layers) stripping fields, a fake/mock Redis server, or a non-Redis service on the port.","commonSituations":"Pointing Jedis at a proxy or TLS-terminating middlebox that mangles RESP3 HELLO; connecting to an incompatible or mock server in tests; unusual/old server builds replying to HELLO without the protover field.","solutions":["Verify the endpoint is a real Redis server >= 6.0 that answers HELLO fully (run HELLO manually via redis-cli)","Bypass or reconfigure the proxy so HELLO replies are passed through unmodified","Force RESP2 (protocol 2) in the client config so HELLO negotiation is avoided if the server/proxy cannot handle it","Check server version compatibility and upgrade Redis or the middleware"],"exampleFix":"// before\nJedisClient c = RedisClient.builder()\n    .hostAndPort(proxyHost, 6379) // proxy drops HELLO protover\n    .build();\n// after\nJedisClient c = RedisClient.builder()\n    .hostAndPort(redisHost, 6379) // real Redis, or\n    .protocol(RedisProtocol.RESP2) // skip HELLO negotiation\n    .build();","handlingStrategy":"try-catch","validationCode":"// before connecting: verify endpoint\n// redis-cli -h host -p port HELLO  -> must include a 'proto' field","typeGuard":null,"tryCatchPattern":"try { client = RedisClient.builder().hostAndPort(h, p).build(); } catch (JedisConnectionException | IllegalStateException e) { log.error(\"HELLO handshake incomplete; check server/proxy\", e); }","preventionTips":["Confirm HELLO works via redis-cli before wiring the client","Avoid proxies that rewrite RESP handshake traffic","Force RESP2 for older servers or constrained middleboxes","Keep Redis >= 6.0 for HELLO/RESP3 support"],"tags":["jedis","handshake","hello","resp3"],"backgroundTag":"unexpected-response-shape","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"}