dianping/cat · critical · RuntimeException

Error message type : %s

Error message

Error message type : %s

What it means

CodecHandler.decode dispatches on the 3-byte protocol hint at the start of an incoming message buffer: 'PT1' -> plain text, 'NT1' -> native binary, 'NM1' -> metric bag. Any other hint throws RuntimeException("Error message type : <hint>"). This guard sits at the entry of server-side message decoding, so garbage or mismatched payloads fail here first.

Source

Thrown at cat-core/src/main/java/com/dianping/cat/message/CodecHandler.java:59

		MessageTree tree;

		buf.getBytes(4, data);
		String hint = new String(data);

		if ("PT1".equals(hint)) {
			tree = m_plainTextCodec.decode(buf);
		} else if ("NT1".equals(hint)) {
			tree = m_nativeCodec.decode(buf);
		} else if ("NM1".equals(hint)) {
			MetricBag bag = m_metricBagDecoder.decode(buf);

			tree = new DefaultMessageTree();
			tree.setDomain(bag.getDomain());
			tree.setIpAddress(bag.getIpAddress());
			tree.setHostName(bag.getHostName());
			tree.getMetrics().addAll(bag.getMetrics());
		} else {
			throw new RuntimeException("Error message type : " + hint);
		}

		MessageTreeFormat.format(tree);
		return tree;
	}

}

View on GitHub (pinned to e815e74d4c)

Solutions

  1. Hex-dump the first bytes of the failing buffer to see the actual hint string.
  2. Verify client and server CAT versions agree on the wire protocol (PT1/NT1/NM1).
  3. Ensure only CAT clients route to this port; keep health checks/probes off it or make them send nothing.
  4. Check ByteBuf handling: slice/duplicate without resetting readerIndex, or reading the hint twice, will shift bytes and corrupt dispatch.

Example fix

// before (double-read corrupts hint)
String peek = buf.toString(0, 3, CharsetUtil.UTF_8);
tree = handler.decode(buf); // readerIndex still at 0? maybe not

// after
buf.resetReaderIndex();
tree = handler.decode(buf);
Defensive patterns

Strategy: validation

Validate before calling

String hint = buf.toString(buf.readerIndex(), 3, CharsetUtil.UTF_8);
if (!("PT1".equals(hint) || "NT1"equals(hint) || "NM1"equals(hint))) { buf.release(); return; /* drop */ }

Try / catch

catch (RuntimeException e) { if (e.getMessage().startsWith("Error message type")) { close connection; log peer address; } else throw e; }

Prevention

When it happens

Trigger: CodecHandler.decode(buf) where buf's first three bytes are not PT1/NT1/NM1: truncated payloads, random TCP data hitting the CAT port, an incompatible client protocol version, or a buffer whose readerIndex was not reset before decode.

Common situations: A load balancer / health probe connecting to the CAT receiver port and sending arbitrary bytes; old client speaking a retired protocol prefix; Netty ByteBuf reuse bugs where the reader index points mid-message.

Related errors


AI-assisted analysis of dianping/cat@e815e74d4c (2026-08-14). Data as JSON: /api/errors/b55245fe18efefbc. Report an issue: GitHub.