NationalSecurityAgency/ghidra · critical · RuntimeException
Could not start server
Error message
Could not start server
What it means
IsfServer.startServer wraps an IOException from new ServerSocket(port, 50, InetAddress.getLoopbackAddress()) in a RuntimeException('Could not start server'). The ISF server thread could not bind its loopback listener socket. Unlike the DAP variant, this binds to the loopback address and does not append the IOException message, so the underlying cause is only visible in the wrapped exception.
Source
Thrown at Ghidra/Debug/Debugger-isf/src/main/java/ghidra/dbg/isf/IsfServer.java:63
private GhidraProject project;
private int port = 54321;
private IsfClientHandler handler;
private Map<String, DataTypeManager> managers = new HashMap<>();
public IsfServer(GhidraProject project, int port) {
this.project = project;
this.port = port;
handler = new IsfClientHandler(this);
}
public void startServer() {
try {
server = new ServerSocket(port, 50, InetAddress.getLoopbackAddress());
this.start();
}
catch (IOException e) {
throw new RuntimeException("Could not start server");
}
}
public void stopServer() {
running = false;
this.interrupt();
for (DataTypeManager m : managers.values()) {
m.close();
}
}
@Override
public void run() {
running = true;
while (running) {
try {
Msg.info(this, "Listening for a connection...");
View on GitHub (pinned to d5f144c24d)
Solutions
- Stop any previously started IsfServer (call stopServer() and ensure its ServerSocket is closed) before starting a new one.
- Choose a different, free port for the ISF server.
- Reproduce with a direct ServerSocket bind on loopback to capture the real IOException (BindException).
- Wrap/propagate IOException instead of a bare RuntimeException so callers can react to the bind failure.
Example fix
// before
try {
server = new ServerSocket(port, 50, InetAddress.getLoopbackAddress());
this.start();
} catch (IOException e) {
throw new RuntimeException("Could not start server");
}
// after
try {
server = new ServerSocket(port, 50, InetAddress.getLoopbackAddress());
this.start();
} catch (IOException e) {
throw new RuntimeException("Could not start ISF server on loopback:" + port, e);
} Defensive patterns
Strategy: try-catch
Validate before calling
try (ServerSocket probe = new ServerSocket(port, 50, InetAddress.getLoopbackAddress())) {
// free; close probe and let IsfServer bind
} catch (IOException e) {
// choose another port before startServer()
} Try / catch
try {
server.startServer();
} catch (RuntimeException e) {
// ISF server bind failed; stop prior instance and/or pick a new port
} Prevention
- Call stopServer() and ensure the prior ServerSocket is closed before restarting.
- Use a free loopback port for the ISF server.
- Wrap the IOException so the real cause (BindException) is visible.
When it happens
Trigger: startServer() is called when the configured port is already bound (e.g. another ISF server instance still running), or socket creation fails. Bind is to InetAddress.getLoopbackAddress() (127.0.0.1), so non-loopback/permission address issues are limited.
Common situations: A prior IsfServer was not stopped (stopServer sets running=false, interrupts the thread, closes managers but the ServerSocket close is not shown here); port collision with another loopback service; OS refusing socket allocation under resource exhaustion.
Related errors
- Could not start server
- port must be numeric
- address must be 'port' or 'host:port'
- 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/363f7e08365d459e.
Report an issue: GitHub.