eclipse-vertx/vert.x · error · WebSocketHandshakeException
Invalid WebSocket location
Error message
Invalid WebSocket location
What it means
This WebSocketHandshakeException is thrown in createHandshaker when HttpUtils.getWebSocketLocation(request, isSsl()) throws while computing the WebSocket location (the ws/wss URL derived from the request Host and URI). Vert.x responds 400 with "Invalid request URI" and aborts the handshake.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerConnection.java:390
request.response()
.setStatusCode(BAD_REQUEST.code())
.end("\"Connection\" header must be \"Upgrade\".");
throw new WebSocketHandshakeException("Invalid connection header");
}
if (request.method() != io.vertx.core.http.HttpMethod.GET) {
request.response()
.setStatusCode(METHOD_NOT_ALLOWED.code())
.end();
throw new WebSocketHandshakeException("Invalid HTTP method");
}
String wsURL;
try {
wsURL = HttpUtils.getWebSocketLocation(request, isSsl());
} catch (Exception e) {
request.response()
.setStatusCode(BAD_REQUEST.code())
.end("Invalid request URI");
throw new WebSocketHandshakeException("Invalid WebSocket location", e);
}
String subProtocols = null;
if (webSocketConfig.getSubProtocols() != null) {
subProtocols = String.join(",", webSocketConfig.getSubProtocols());
}
WebSocketDecoderConfig config = WebSocketDecoderConfig.newBuilder()
.allowExtensions(webSocketConfig.getUsePerMessageCompression() || webSocketConfig.getUsePerFrameCompression())
.maxFramePayloadLength(webSocketConfig.getMaxFrameSize())
.allowMaskMismatch(webSocketConfig.isUseUnmaskedFrames())
.closeOnProtocolViolation(false)
.build();
WebSocketServerHandshakerFactory factory = new WebSocketServerHandshakerFactory(wsURL, subProtocols, config);
WebSocketServerHandshaker shake = factory.newHandshaker(request.nettyRequest());
if (shake != null) {
return shake;
}
// See WebSocketServerHandshakerFactory.sendUnsupportedVersionResponse(ch);
request.response()View on GitHub (pinned to fb308bd8c3)
Solutions
- Ensure the client sends a valid Host header with the correct host and port (HTTP/1.1 requires Host).
- Configure the proxy/load balancer to preserve the Host header.
- Check the request URI for malformed characters and fix the client URL.
- Catch WebSocketHandshakeException in your upgrade handler and return a descriptive 400 so clients can diagnose the bad request.
Example fix
// before (client through proxy losing Host)
httpClient.request(HttpMethod.GET, "http://backend/ws");
// after
httpClient.request(HttpMethod.GET, "http://backend/ws")
.compose(req -> req.putHeader("Host", "backend:8080").send()); Defensive patterns
Strategy: validation
Validate before calling
String host = request.getHeader(HttpHeaders.HOST);
if (host == null || host.isEmpty()) {
// cannot derive WebSocket location; reject early
} Try / catch
try {
serverRequest.toWebSocket();
} catch (WebSocketHandshakeException e) {
respondBadRequest("Invalid request URI");
} Prevention
- Require HTTP/1.1 (with Host header) for WebSocket upgrades
- Configure proxies to preserve the Host header
- Validate client URLs for malformed URIs before connecting
When it happens
Trigger: A WebSocket upgrade request with a malformed or missing Host header, or an unusable request URI such that the WebSocket location URL cannot be constructed (any exception from getWebSocketLocation).
Common situations: Requests through proxies that drop or rewrite the Host header; HTTP/1.0 requests without Host; clients sending absolute-form or malformed request URIs; unusual Host headers that break URI building (e.g. invalid port).
Understand the failure class
Background: "Invalid URL" errors: why new URL(), URI.parse, and reqwest::Url reject your string — missing scheme, whitespace, and bad path format — this error's family across 39 libraries.
Related errors
- Invalid connection header
- Invalid HTTP method
- Invalid WebSocket version
- Protocol version ${version} not supported.
- maxWebSockets must be > 0 or -1 (disabled)
AI-assisted analysis of eclipse-vertx/vert.x@fb308bd8c3 (2026-09-06).
Data as JSON: /api/errors/629e054f001ffded.
Report an issue: GitHub.