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
- Chunk large payloads into multiple messages each under 64 KiB (e.g. write memory in <= 60 KiB blocks).
- Reduce the size of a single message by paginating object/value lists or streaming snapshots in pieces.
- If a legitimate single value exceeds the cap, restructure the protocol usage so no one field carries the full payload.
- 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
- Cap each memory/value payload well under 64 KiB and chunk large transfers.
- Paginate repeated/bulk fields in a single message.
- Check msg.getSerializedSize() before serializing large requests.
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
- Cannot receive TraceRmi message with excessive message lengt
- Could not receive negotiation request
- Could not respond during negotiation
- Protocol error: Invalid value kinds
- Could not send request
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/9e43944950c52261.
Report an issue: GitHub.