redis/jedis · error · JedisException

Unknown message type

Error message

Unknown message type: <firstObj>

What it means

During the subscribe loop, JedisPubSubBase.process reads each pub/sub reply as a list whose first element must be the command name as bytes (e.g. 'subscribe', 'message', 'pong'). If the first element of a list reply is not a byte[], the reply does not conform to the RESP2 pub/sub message layout, and this JedisException ('Unknown message type: ...') is thrown (JedisPubSubBase.java:144).

Solutions

  1. Use a dedicated connection for pub/sub (do not share with normal commands).
  2. Ensure protocol matches expectations (RESP2 for classic pub/sub semantics, or upgrade Jedis for RESP3 push handling).
  3. Check for intermediaries (proxies, RESP translators) that alter pub/sub reply format; capture the printed firstObj to identify the unexpected type.
Defensive patterns

Strategy: try-catch

Validate before calling

// before subscribing, verify connection is exclusive to pub/sub
if (!jedis.getConnection().equals(pubSubConnection)) {
  throw new IllegalStateException("pub/sub requires a dedicated connection");
}

Type guard

if (reply instanceof java.util.List
    && !((java.util.List<?>) reply).isEmpty()
    && ((java.util.List<?>) reply).get(0) instanceof byte[]) {
  // valid pub/sub message layout
}

Try / catch

try {
  pubSub.proceed(jedis, channel);
} catch (JedisException e) {
  if (e.getMessage().startsWith("Unknown message type:")) {
    // close connection; reopen on dedicated pub/sub connection
  }
}

Prevention

When it happens

Trigger: process() (via proceed/proceedWithPatterns) receives a list-typed reply whose element 0 is not a byte[] — e.g. a RESP3 push/other message shape, an error object, or a non-pub/sub reply interleaved on the connection.

Common situations: Mixing regular commands and pub/sub on the same connection, RESP3 protocol where replies arrive as push types not matching the expected layout, or server/proxy versions emitting non-standard pub/sub payloads.

Related errors


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

Appendix: source

Thrown at src/main/java/redis/clients/jedis/JedisPubSubBase.java:144

    } finally {
      authenticator.client.setActiveSubscription(false);
      authenticator.client.rollbackTimeout();
    }
  }

  protected abstract T encode(byte[] raw);

  //  private void process(Client client) {
  private void process() {

    do {
      Object reply = authenticator.client.getUnflushedObject();

      if (reply instanceof List) {
        List<Object> listReply = (List<Object>) reply;
        final Object firstObj = listReply.get(0);
        if (!(firstObj instanceof byte[])) {
          throw new JedisException("Unknown message type: " + firstObj);
        }
        final byte[] resp = (byte[]) firstObj;
        if (Arrays.equals(SUBSCRIBE.getRaw(), resp)) {
          subscribedChannels = ((Long) listReply.get(2)).intValue();
          final byte[] bchannel = (byte[]) listReply.get(1);
          final T enchannel = (bchannel == null) ? null : encode(bchannel);
          onSubscribe(enchannel, subscribedChannels);
        } else if (Arrays.equals(UNSUBSCRIBE.getRaw(), resp)) {
          subscribedChannels = ((Long) listReply.get(2)).intValue();
          final byte[] bchannel = (byte[]) listReply.get(1);
          final T enchannel = (bchannel == null) ? null : encode(bchannel);
          onUnsubscribe(enchannel, subscribedChannels);
        } else if (Arrays.equals(MESSAGE.getRaw(), resp)) {
          final byte[] bchannel = (byte[]) listReply.get(1);
          final Object mesg = listReply.get(2);
          final T enchannel = (bchannel == null) ? null : encode(bchannel);
          if (mesg instanceof List) {
            ((List<byte[]>) mesg).forEach(bmesg -> onMessage(enchannel, encode(bmesg)));

View on GitHub (pinned to 6dac31d4c2)