NationalSecurityAgency/ghidra · error · TraceRmiError

Cannot send TraceRmi message with excessive length

Error message

Cannot send TraceRmi message with excessive length

What it means

Thrown by TraceRmiHandler.sendDelimited when a RootMessage being serialized exceeds MAX_MSG_LENGTH (1 << 16 = 64 KiB). The length-prefix framing protocol caps message size to avoid unbounded memory allocation, so an oversized message is refused before it is written to the socket. This is a hard protocol limit defined at TraceRmiHandler.java:79.

Source

Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java:424

	protected RootMessage receive() {
		try {
			// May return null when the socket is closed normally
			return recvDelimited(in);
		}
		catch (IOException e) {
			// Also return null for abnormal closure
			Msg.error(this, "Cannot read packet: " + e);
			flushXReqQueue(e);
			return null;
		}
	}

	protected static void sendDelimited(OutputStream out, RootMessage msg, long dbgSeq)
			throws IOException {
		ByteBuffer buf = ByteBuffer.allocate(Integer.BYTES);
		int len = msg.getSerializedSize();
		if (len > MAX_MSG_LENGTH) {
			throw new TraceRmiError("Cannot send TraceRmi message with excessive length");
		}
		buf.putInt(len);
		out.write(buf.array());
		msg.writeTo(out);
		out.flush();
	}

	protected static byte[] recvAll(InputStream in, int len) throws IOException {
		byte[] buf = new byte[len];
		int total = 0;
		while (total < len) {
			int l = in.read(buf, total, len - total);
			if (l <= 0) {
				return null;
			}
			total += l;
		}
		return buf;

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Chunk large payloads into multiple messages each under 64 KiB (e.g. write memory in <= 60 KiB blocks).
  2. Reduce the size of a single message by paginating object/value lists or streaming snapshots in pieces.
  3. If a legitimate single value exceeds the cap, restructure the protocol usage so no one field carries the full payload.
  4. Confirm you are not accidentally serializing redundant/debug data into the message.

Example fix

# before: one giant write
conn.proxy.put_bytes(start, huge_blob)  # >64KiB

# after: chunked writes
CHUNK = 32 * 1024
off = start
for i in range(0, len(huge_blob), CHUNK):
    conn.proxy.put_bytes(off, huge_blob[i:i+CHUNK])
    off += CHUNK
Defensive patterns

Strategy: validation

Validate before calling

RootMessage msg = req.build();
int len = msg.getSerializedSize();
if (len > TraceRmiHandler.MAX_MSG_LENGTH) {
    // split payload / chunk the operation
    throw new IllegalStateException("message too large: " + len);
}

Try / catch

try {
    TraceRmiHandler.sendDelimited(out, msg, dbgSeq);
} catch (TraceRmiError e) {
    // payload exceeds 64 KiB; chunk and resend
}

Prevention

When it happens

Trigger: A request or reply that serializes to more than 64 KiB: large memory dumps embedded in a single message, a very large value/byte-array payload, a bulk object snapshot, or a request carrying many keys/values at once.

Common situations: Backend writing a large memory region's full contents in one putBytes/setValue call; sending a big register bank or large byte array without chunking; protobuf message with oversized repeated fields.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/9e43944950c52261. Report an issue: GitHub.