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
- Use a dedicated connection for pub/sub (do not share with normal commands).
- Ensure protocol matches expectations (RESP2 for classic pub/sub semantics, or upgrade Jedis for RESP3 push handling).
- 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
- Use one connection exclusively for pub/sub; never share with regular commands.
- Match the pub/sub API to the protocol/feature used (plain vs sharded pub/sub).
- Log the offending firstObj value to identify non-standard replies from proxies/modules.
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
- Blocking pub/sub operations are not supported on…
- Unexpected message
- Unknown message type:
- setHostAndPort method has limited capability.
- Unknown message type
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)