{"record":{"id":"e343a2569920ea94","repo":"NationalSecurityAgency/ghidra","slug":"could-not-receive-negotiation-request","errorCode":null,"errorMessage":"Could not receive negotiation request","messagePattern":"Could not receive negotiation request","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":519,"sourceCode":"\t\t\t\tif (canSend) {\n\t\t\t\t\tcanSend = send(rep);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfinally {\n\t\t\ttry {\n\t\t\t\tdispose();\n\t\t\t}\n\t\t\tcatch (IOException e) {\n\t\t\t\tMsg.error(this, \"Could not close socket after error\", e);\n\t\t\t}\n\t\t}\n\t}\n\n\tprotected void negotiate() {\n\t\tRootMessage req = receive();\n\t\tif (req == null) {\n\t\t\tthrow new TraceRmiError(\"Could not receive negotiation request\");\n\t\t}\n\t\tRootMessage rep = dispatchNegotiate.handle(req);\n\t\tif (!send(rep)) {\n\t\t\tthrow new TraceRmiError(\"Could not respond during negotiation\");\n\t\t}\n\t}\n\n\tprivate interface Dispatcher {\n\t\tRootMessage.Builder dispatch(RootMessage req, RootMessage.Builder rep) throws Exception;\n\n\t\tdefault String exceptionMessage(Throwable exc) {\n\t\t\tString msg = exc.getMessage();\n\t\t\tif (msg == null) {\n\t\t\t\treturn exc.getClass().getCanonicalName();\n\t\t\t}\n\t\t\treturn exc.getClass().getCanonicalName() + \": \" + msg;\n\t\t}\n","sourceCodeStart":501,"sourceCodeEnd":537,"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#L501-L537","documentation":"Thrown during TraceRmiHandler.negotiate() when receive() returns null for the very first message expected on a new connection. A null return means the peer closed the socket, hit EOF, or the read failed before sending the negotiation request. Negotiation is the mandatory handshake that precedes any TraceRmi traffic, so its absence aborts the connection.","triggerScenarios":"A client/backend connects to the TraceRmi server socket but disconnects immediately or sends nothing; the peer crashes during startup before negotiating; a network interruption drops the socket mid-handshake.","commonSituations":"Backend process crashed on launch; wrong address/port causing immediate disconnect; firewall/proxy closing idle handshake; peer is not a TraceRmi client and hangs up; SSL/TLS mismatch causing reset.","solutions":["Check the peer process is alive and its logs for a startup crash.","Confirm the connect address/port points at the TraceRmi server (and that startServer() succeeded).","Retry the connection once after a short delay for transient network resets.","Ensure no intermediary (proxy, firewall) is dropping the socket during the handshake."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if (!socket.isConnected() || socket.isClosed()) {\n    // peer gone; do not attempt negotiation\n}","typeGuard":null,"tryCatchPattern":"try {\n    handler.run(); // invokes negotiate()\n} catch (TraceRmiError e) {\n    // could not receive negotiation request; check peer liveness and retry connect\n}","preventionTips":["Verify the peer process is alive and listening before connecting.","Confirm the address/port is the TraceRmi server (startServer succeeded).","Retry the connection once for transient handshake resets."],"tags":["trace-rmi","negotiation","connection","network"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}