dianping/cat · critical · RuntimeException
Unsupported message type(%s).
Error message
Unsupported message type(%s).
What it means
In NativeMessageCodec.decode, each child message begins with a one-char tag: 't' transaction, 'T' transaction end, 'E' event, 'M' metric, 'H' heartbeat, 'L' trace. The default branch throws RuntimeException("Unsupported message type(%s)." , ch) for any other character, meaning the byte stream is corrupt or misaligned — the decoder is reading where a type tag was expected.
Source
Thrown at cat-core/src/main/java/com/dianping/cat/message/codec/NativeMessageCodec.java:92
Message e = Codec.EVENT.decode(ctx, buf);
ctx.addChild(e);
break;
case 'M':
Codec.METRIC.decode(ctx, buf);
break;
case 'H':
Message h = Codec.HEARTBEAT.decode(ctx, buf);
ctx.addChild(h);
break;
case 'L':
Message l = Codec.TRACE.decode(ctx, buf);
ctx.addChild(l);
break;
default:
throw new RuntimeException(String.format("Unsupported message type(%s).", ch));
}
}
if (msg == null) {
msg = ctx.getMessageTree().getMessage();
}
return msg;
}
@Override
public ByteBuf encode(MessageTree tree) {
ByteBuf buf = PooledByteBufAllocator.DEFAULT.buffer(4 * 1024);
try {
Context ctx = new Context(tree);
buf.writeInt(0); // place-holderView on GitHub (pinned to e815e74d4c)
Solutions
- Dump the buffer around the failure offset; verify the byte where decoding stopped is one of t/T/E/M/H/L.
- Confirm encoder and decoder run the same NativeMessageCodec version on both ends (upgrade together).
- Check the Netty pipeline framing (split frames, missing length-field prep) and the CAT server's max-message-size/child-message limits.
- Guard against double-decode of the same ByteBuf (retain/release and readerIndex bugs).
Example fix
// before: no size guard, oversized tree arrives truncated serverSocketHandler.decode(buf); // mid-tree byte != tag -> throws // after: enforce same limits both ends int MAX = 8192; // align with server child-message cap if (tree.getMessages().size() > MAX) tree.getMessages().subList(MAX, tree.getMessages().size()).clear();
Defensive patterns
Strategy: try-catch
Try / catch
catch (RuntimeException e) { if (e.getMessage().startsWith("Unsupported message type")) { log corrupt peer + offset; drop connection; } else throw e; } Prevention
- Use length-prefixed framing; never delimiter framing for binary CAT traffic.
- Deploy client/server codec versions together.
- Cap and test oversized message trees against the server's child limit.
When it happens
Trigger: Decoding an NT1 buffer whose framing is broken: a truncated message, a payload truncated by TCP message-size limits, field-order mismatch between encoder/decoder versions, or a buffer accidentally double-decoded so the cursor sits on a data byte rather than a tag.
Common situations: Cat-client and cat-core protocol drift after partial upgrades; Netty frame decoders (DelimiterBased/LengthBased) misconfigured so messages split mid-record; payloads exceeding server-side max message size and being silently cut.
Related errors
- Malformed variable int %s!
- Error message type : %s
- Unrecognized version(%s) for binary message codec!
- Unrecognized version(%s) for binary metric bag!
- Malformed variable int %s!
AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14).
Data as JSON: /api/errors/5d2c2baf87cf882c.
Report an issue: GitHub.