NationalSecurityAgency/ghidra · critical · TraceRmiError
Could not respond during negotiation
Error message
Could not respond during negotiation
What it means
Thrown during TraceRmiHandler.negotiate() after the request was received and a reply built, but send(rep) returns false, meaning the response could not be written back to the peer. The handshake is therefore incomplete and the connection is unusable.
Solutions
- Increase the peer's handshake timeout so it waits for the reply.
- Verify network stability between frontend and backend for transient drops.
- Check the peer did not crash between request and reply (peer logs).
- Re-establish the connection from scratch.
Defensive patterns
Strategy: retry
Try / catch
try {
handler.run();
} catch (TraceRmiError e) {
// reply could not be sent; peer likely disconnected; reconnect
} Prevention
- Ensure the peer waits long enough to read the negotiation reply.
- Check peer logs for a crash between request and reply.
- Re-establish the connection rather than reuse the broken socket.
When it happens
Trigger: The peer closed its side of the socket between sending the negotiation request and reading the reply; an IOException occurred while writing the reply; the output stream is broken.
Common situations: Peer timed out waiting and disconnected; network glitch mid-handshake; peer crashed right after sending its request; socket write buffer closed.
Related errors
- Could not receive negotiation request
- Could not send request
- Socket closed
- ADDRESS must be HOST:PORT
- ADDRESS must be PORT or HOST:PORT
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/c39f4bcc085d37d4.
Report an issue: GitHub.
Appendix: source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java:523
}
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;
}
default RootMessage handle(RootMessage req) {
String desc = toString(req);
if (desc != null) {
TimedMsg.debug(this, "HANDLING: " + desc);View on GitHub (pinned to d5f144c24d)