{"record":{"id":"a39e7b14d7dd3ce0","repo":"redis/jedis","slug":"unknown-message-type-firstobj-a39e7b","errorCode":null,"errorMessage":"Unknown message type: <firstObj>","messagePattern":"Unknown message type: <firstObj>","errorType":"exception","errorClass":"JedisException","httpStatus":null,"severity":"error","filePath":"src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java","lineNumber":84,"sourceCode":"      process();\n    } finally {\n      authenticator.client.setActiveSubscription(false);\n      authenticator.client.rollbackTimeout();\n    }\n  }\n\n  protected abstract T encode(byte[] raw);\n\n  private void process() {\n\n    do {\n      Object reply = authenticator.client.getUnflushedObject();\n\n      if (reply instanceof List) {\n        List<Object> listReply = (List<Object>) reply;\n        final Object firstObj = listReply.get(0);\n        if (!(firstObj instanceof byte[])) {\n          throw new JedisException(\"Unknown message type: \" + firstObj);\n        }\n        final byte[] resp = (byte[]) firstObj;\n        if (Arrays.equals(SSUBSCRIBE.getRaw(), resp)) {\n          subscribedChannels = ((Long) listReply.get(2)).intValue();\n          final byte[] bchannel = (byte[]) listReply.get(1);\n          final T enchannel = (bchannel == null) ? null : encode(bchannel);\n          onSSubscribe(enchannel, subscribedChannels);\n        } else if (Arrays.equals(SUNSUBSCRIBE.getRaw(), resp)) {\n          subscribedChannels = ((Long) listReply.get(2)).intValue();\n          final byte[] bchannel = (byte[]) listReply.get(1);\n          final T enchannel = (bchannel == null) ? null : encode(bchannel);\n          onSUnsubscribe(enchannel, subscribedChannels);\n        } else if (Arrays.equals(SMESSAGE.getRaw(), resp)) {\n          final byte[] bchannel = (byte[]) listReply.get(1);\n          final byte[] bmesg = (byte[]) listReply.get(2);\n          final T enchannel = (bchannel == null) ? null : encode(bchannel);\n          final T enmesg = (bmesg == null) ? null : encode(bmesg);\n          onSMessage(enchannel, enmesg);","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/redis/jedis/blob/6dac31d4c224fb3257c216f3985340c6f500cdcb/src/main/java/redis/clients/jedis/JedisShardedPubSubBase.java#L66-L102","documentation":"JedisShardedPubSubBase.process() expects each pub/sub reply to be a List whose first element is a byte[] naming the reply command (e.g. SSUBSCRIBE, SUNSUBSCRIBE, SMESSAGE). If the first element of the list is not a byte[], the reply type cannot be identified and it throws JedisException(\"Unknown message type: \" + firstObj).","triggerScenarios":"proceed() loop receives a List reply whose element 0 is not a byte[] (e.g. a Long/complex RESP value) on the sharded pub/sub connection, indicating protocol desync or an unexpected server response.","commonSituations":"Using a connection with leftover replies before SSUBSCRIBE; server/protocol mismatch (RESP3 push frames interpreted oddly); custom proxies or RESP translators reshaping replies.","solutions":["Use a clean dedicated connection for sharded pub/sub with SSUBSCRIBE as the first command.","Verify RESP protocol setting (prefer RESP3) matches the server capability.","Remove any proxy/middleware between client and Redis or ensure it preserves RESP framing.","Catch JedisException and re-establish the subscription on a fresh connection."],"exampleFix":"// before\nJedis j = pool.getResource();\nj.xlen(\"stream\");           // stale reply\nshardedPubSub.ssubscribe(j, channel); // desync\n// after\ntry (Jedis j = pool.getResource()) {\n  shardedPubSub.ssubscribe(j, channel); // first and only command on connection\n}","handlingStrategy":"try-catch","validationCode":"// before subscribing ensure no pending replies\nif (!jedis.getConnection().isBroken()) { /* ok */ } else { jedis.close(); }","typeGuard":"boolean isShardedPubSubReply(Object reply) {\n  return reply instanceof List\n      && ((List<?>) reply).get(0) instanceof byte[];\n}","tryCatchPattern":"try {\n  shardedPubSub.ssubscribe(jedis, channel);\n} catch (JedisException e) {\n  if (e.getMessage().startsWith(\"Unknown message type\")) {\n    jedis.close(); // fresh connection, re-subscribe\n  } else throw e;\n}","preventionTips":["Issue SSUBSCRIBE as the first command on a dedicated connection.","Use RESP3 for sharded pub/sub against Redis 7+.","Avoid proxies that rewrite RESP framing.","Upgrade Jedis when connecting to newer Redis servers."],"tags":["pubsub","protocol-desync","redis"],"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"}