eclipse-vertx/vert.x · error · WebSocketHandshakeException
Invalid WebSocket version
Error message
Invalid WebSocket version
What it means
This WebSocketHandshakeException is thrown in createHandshaker when the client requests an unsupported WebSocket sub-version in the Sec-WebSocket-Version header (only version 13 is supported). Vert.x responds with 426/Upgrade Required and includes a Sec-WebSocket-Version header advertising version 13.
Source
Thrown at vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerConnection.java:412
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()
.putHeader(HttpHeaderNames.SEC_WEBSOCKET_VERSION, WebSocketVersion.V13.toHttpHeaderValue())
.setStatusCode(UPGRADE_REQUIRED.code())
.end();
throw new WebSocketHandshakeException("Invalid WebSocket version");
}
public void netSocket(Handler<AsyncResult<NetSocket>> handler) {
Future<NetSocket> fut = netSocket();
if (handler != null) {
fut.onComplete(handler);
}
}
public Future<NetSocket> netSocket() {
Promise<NetSocket> promise = context.promise();
netSocket(promise);
return promise.future();
}
void netSocket(Promise<NetSocket> promise) {
context.execute(() -> {
View on GitHub (pinned to fb308bd8c3)
Solutions
- Update the client to send Sec-WebSocket-Version: 13 (or omit it; modern libraries default to 13).
- Upgrade the legacy WebSocket client library to an RFC 6455-compliant one.
- Handle the 426 Upgrade Required response on the client and retry with version 13 as advertised in the response's Sec-WebSocket-Version header.
- For genuinely legacy clients, place a translation layer/gateway that rewrites the handshake to version 13.
Example fix
// before (client)
request.putHeader("Sec-WebSocket-Version", "8");
// after
request.putHeader("Sec-WebSocket-Version", "13"); Defensive patterns
Strategy: validation
Validate before calling
String ver = request.getHeader(HttpHeaders.SEC_WEBSOCKET_VERSION);
if (ver == null || !"13".equals(ver.trim())) {
// send 426 with Sec-WebSocket-Version: 13
} Try / catch
try {
serverRequest.toWebSocket();
} catch (WebSocketHandshakeException e) {
respondUpgradeRequired();
} Prevention
- Only use RFC 6455 (version 13) WebSocket clients
- Upgrade legacy libraries that send Sec-WebSocket-Version: 8 or lower
- Implement client handling of 426 Upgrade Required responses
When it happens
Trigger: Client sends Sec-WebSocket-Version: 8 (Hixie-76/hybi-00 era clients), 7, or any value other than 13 during the WebSocket upgrade, and the server then calls the upgrade path (createHandshaker from createWebSocket).
Common situations: Very old browsers or legacy WebSocket client libraries (pre-RFC6455 draft versions); hand-rolled clients hardcoding an outdated version header; older corporate tooling behind the upgrade endpoint.
Related errors
- Invalid connection header
- Invalid HTTP method
- Invalid WebSocket location
- 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/eb80af799f7963d1.
Report an issue: GitHub.