NationalSecurityAgency/ghidra · error · TraceRmiError
Could not send request
Error message
Could not send request
What it means
Thrown when invoking an asynchronous remote method and sendDelimited fails with an IOException while writing the request to the socket. The IOException is wrapped in TraceRmiError. It indicates the output side of the connection is broken (closed stream, reset socket, broken pipe).
Source
Thrown at Ghidra/Debug/Debugger-rmi-trace/src/main/java/ghidra/app/plugin/core/debug/service/tracermi/TraceRmiHandler.java:1281
.addAllArguments(
arguments.entrySet().stream().map(TraceRmiHandler::makeArgument).toList());
DefaultRemoteAsyncResult result;
if (open != null) {
result = new DefaultRemoteAsyncResult(open);
invoke.setOid(open.doId.toDomObjId());
}
else {
result = new DefaultRemoteAsyncResult();
}
req.setXrequestInvokeMethod(invoke);
synchronized (xReqQueue) {
xReqQueue.offer(result);
synchronized (out) {
try {
sendDelimited(out, req.build(), dbgSeq++);
}
catch (IOException e) {
throw new TraceRmiError("Could not send request", e);
}
}
return result;
}
}
@Override
public long getLastSnapshot(Trace trace) {
OpenTrace byTrace = openTraces.getByTrace(trace);
if (byTrace == null) {
throw new NoSuchElementException();
}
TraceSnapshot lastSnapshot = byTrace.lastSnapshot;
if (lastSnapshot == null) {
return 0;
}
return lastSnapshot.getKey();
}View on GitHub (pinned to d5f144c24d)
Solutions
- Check the connection/handler is still alive (not disposed) before invoking; reconnect if closed.
- Inspect logs for the peer's reason for closing the socket.
- Catch TraceRmiError around invokeAsync and re-establish the connection, then retry idempotent operations.
- Avoid invoking methods after explicitly disposing the connection.
Example fix
// before
method.invokeAsync(args).toCompletableFuture().join();
// after
try {
method.invokeAsync(args).toCompletableFuture().join();
} catch (TraceRmiError e) {
// connection lost; reconnect and retry if idempotent
reconnect();
} Defensive patterns
Strategy: try-catch
Validate before calling
if (handler.isDisposed() || socket.isClosed()) {
throw new IllegalStateException("connection closed; cannot send");
} Try / catch
try {
method.invokeAsync(args).toCompletableFuture().join();
} catch (TraceRmiError e) {
// output broken; reconnect then retry idempotent ops
} Prevention
- Check the handler/connection is alive before invoking remote methods.
- Do not invoke methods after disposing the connection.
- Catch TraceRmiError around async invocations and reconnect for transient failures.
When it happens
Trigger: Calling a RemoteMethod.invokeAsync(...) after the server closed the connection; the socket was disposed; the peer crashed mid-session; network drop severed the write path.
Common situations: Server/frontend process exited; connection timed out and was closed; long-running session lost network; invoking methods on a disposed handler.
Related errors
- Could not receive negotiation request
- Could not respond during negotiation
- Socket closed
- Usage: ghidra trace connect ADDRESS
- ADDRESS must be HOST:PORT
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/4e3674f5ac3cb2ac.
Report an issue: GitHub.