{"record":{"id":"36aa63ed6252cff5","repo":"NationalSecurityAgency/ghidra","slug":"cannot-receive-tracermi-message-with-excessive-mes","errorCode":null,"errorMessage":"Cannot receive TraceRmi message with excessive message length","messagePattern":"Cannot receive TraceRmi message with excessive message length","errorType":"exception","errorClass":"TraceRmiError","httpStatus":null,"severity":"critical","filePath":"Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java","lineNumber":452,"sourceCode":"\t\tint total = 0;\n\t\twhile (total < len) {\n\t\t\tint l = in.read(buf, total, len - total);\n\t\t\tif (l <= 0) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\ttotal += l;\n\t\t}\n\t\treturn buf;\n\t}\n\n\tprotected static RootMessage recvDelimited(InputStream in) throws IOException {\n\t\tbyte[] lenBuf = recvAll(in, Integer.BYTES);\n\t\tif (lenBuf == null) {\n\t\t\treturn null;\n\t\t}\n\t\tint len = ByteBuffer.wrap(lenBuf).getInt();\n\t\tif (len > MAX_MSG_LENGTH) {\n\t\t\tthrow new TraceRmiError(\n\t\t\t\t\"Cannot receive TraceRmi message with excessive message length\");\n\t\t}\n\t\tbyte[] datBuf = recvAll(in, len);\n\t\tif (datBuf == null) {\n\t\t\treturn null;\n\t\t}\n\t\tRootMessage msg = RootMessage.parseFrom(datBuf);\n\t\treturn msg;\n\t}\n\n\tlong dbgSeq = 0;\n\n\tprotected boolean send(RootMessage rep) {\n\t\ttry {\n\t\t\tsynchronized (out) {\n\t\t\t\tsendDelimited(out, rep, dbgSeq++);\n\t\t\t}\n\t\t\treturn true;","sourceCodeStart":434,"sourceCodeEnd":470,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java#L434-L470","documentation":"Thrown by TraceRmiHandler.recvDelimited when the 4-byte length prefix read from the socket exceeds MAX_MSG_LENGTH (64 KiB). This is a defensive guard against a malformed or hostile peer sending an implausibly large framing length, which would otherwise trigger a huge allocation (OOM). It signals a protocol desync or an incompatible/buggy peer.","triggerScenarios":"The remote endpoint writes a length prefix larger than 64 KiB; the byte stream is corrupted so the length field is garbage; the peer runs a different protocol version that uses different framing; a partial/offset read desynchronized the stream.","commonSituations":"Connecting a Ghidra TraceRmi backend of an incompatible version; connecting to a port that is not a TraceRmi server; socket corruption; a backend that violates the 64 KiB cap when sending.","solutions":["Verify client and server run compatible Ghidra versions (TraceRmiHandler.VERSION, currently '12.2').","Confirm the socket endpoint is actually a TraceRmi server and not another service.","Treat this as fatal for the connection: close the socket and re-establish it, rather than trying to resync a desynced stream.","Inspect backend logs for the matching 'excessive length' send-side error to find which side is malformed."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n    RootMessage msg = TraceRmiHandler.recvDelimited(in);\n} catch (TraceRmiError e) {\n    // peer sent an oversized/invalid length; close socket and reconnect\n    socket.close();\n}","preventionTips":["Pin client and server to compatible Ghidra versions sharing the same framing.","Ensure the connected endpoint is a TraceRmi server, not an unrelated service.","Treat a bad length prefix as fatal for that connection; do not attempt stream resync."],"tags":["trace-rmi","message-size","protocol","network","security"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}