NationalSecurityAgency/ghidra · critical · TraceRmiError

Could not receive negotiation request

Error message

Could not receive negotiation request

What it means

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.

Source

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

				if (canSend) {
					canSend = send(rep);
				}
			}
		}
		finally {
			try {
				dispose();
			}
			catch (IOException e) {
				Msg.error(this, "Could not close socket after error", e);
			}
		}
	}

	protected void negotiate() {
		RootMessage req = receive();
		if (req == null) {
			throw new TraceRmiError("Could not receive negotiation request");
		}
		RootMessage rep = dispatchNegotiate.handle(req);
		if (!send(rep)) {
			throw new TraceRmiError("Could not respond during negotiation");
		}
	}

	private interface Dispatcher {
		RootMessage.Builder dispatch(RootMessage req, RootMessage.Builder rep) throws Exception;

		default String exceptionMessage(Throwable exc) {
			String msg = exc.getMessage();
			if (msg == null) {
				return exc.getClass().getCanonicalName();
			}
			return exc.getClass().getCanonicalName() + ": " + msg;
		}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Check the peer process is alive and its logs for a startup crash.
  2. Confirm the connect address/port points at the TraceRmi server (and that startServer() succeeded).
  3. Retry the connection once after a short delay for transient network resets.
  4. Ensure no intermediary (proxy, firewall) is dropping the socket during the handshake.
Defensive patterns

Strategy: retry

Validate before calling

if (!socket.isConnected() || socket.isClosed()) {
    // peer gone; do not attempt negotiation
}

Try / catch

try {
    handler.run(); // invokes negotiate()
} catch (TraceRmiError e) {
    // could not receive negotiation request; check peer liveness and retry connect
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


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