oracle/graal · error · IOException
handshake timeout
Error message
handshake timeout
What it means
Thrown by HandshakeController.handshake when the socket read waiting for the JDWP-Handshake gesture raises SocketTimeoutException. The agent reads the 14-byte greeting with a bounded SO_TIMEOUT; if the accepted peer sends nothing within that window, the read times out and handshake setup fails with IOException("handshake timeout").
Source
Thrown at espresso/src/com.oracle.truffle.espresso.jdwp/src/com/oracle/truffle/espresso/jdwp/impl/HandshakeController.java:117
currentServerSocket = null;
}
}
/**
* Handshake with the debugger.
*/
static boolean handshake(Socket s) throws IOException {
byte[] hello = JDWP_HANDSHAKE.getBytes(StandardCharsets.UTF_8);
byte[] b = new byte[hello.length];
int received = 0;
while (received < hello.length) {
int n;
try {
n = s.getInputStream().read(b, received, hello.length - received);
} catch (SocketTimeoutException x) {
throw new IOException("handshake timeout");
}
if (n < 0) {
s.close();
throw new IOException("handshake failed - connection prematurely closed");
}
received += n;
}
for (int i = 0; i < hello.length; i++) {
if (b[i] != hello[i]) {
throw new IOException("handshake failed - unrecognized message from the debugger");
}
}
// handshake received, so return the gesture to establish the jdwp transport
s.getOutputStream().write(hello);
return true;
}
}View on GitHub (pinned to a66e9ccd1d)
Solutions
- Ensure the debugger actively sends the handshake immediately after connecting
- Keep health-check/probe traffic off the JDWP port
- Allow only trusted source IPs through the firewall to the debug port
- Retry the debugger connection; transient probes will not re-connect
Defensive patterns
Strategy: retry
Try / catch
catch (IOException e) when message contains 'handshake timeout': distinguish from app failure, log, and let the accept loop retry; the debugger can reconnect.
Prevention
- Keep TCP health checks and port scans away from the JDWP port
- Ensure the debugger actively sends the handshake immediately after connecting
When it happens
Trigger: A TCP client connects to the JDWP port but stalls before sending the 'JDWP-Handshake' bytes: half-open connections, firewalls that complete the TCP handshake but drop payload, or an IDE that connects lazily and waits for user action.
Common situations: Port scanners and service-discovery probes (connect then go quiet), NAT/firewall middleboxes, or load balancers doing TCP health checks against the debug port.
Understand the failure class
- SSL/TLS and certificate errors — how TLS handshakes and certificate validation fail.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- Unable to handshake with debugger
- handshake failed - connection prematurely closed
- handshake failed - unrecognized message from the debugger
- Invalid JDWP option value: {key} can be only 'y' or 'n'.
- JDWP options must be a comma separated list of key=value pai
AI-assisted analysis of oracle/graal@a66e9ccd1d (2026-08-14).
Data as JSON: /api/errors/3dbeb27480ca982e.
Report an issue: GitHub.