{"record":{"id":"ed13e8f6603036c1","repo":"eclipse-vertx/vert.x","slug":"invalid-http-method","errorCode":null,"errorMessage":"Invalid HTTP method","messagePattern":"Invalid HTTP method","errorType":"http","errorClass":"WebSocketHandshakeException","httpStatus":405,"severity":"error","filePath":"vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerConnection.java","lineNumber":381,"sourceCode":"    });\n  }\n\n  public WebSocketServerHandshaker createHandshaker(Http1ServerRequest request) throws WebSocketHandshakeException {\n    // As a fun part, Firefox 6.0.2 supports Websockets protocol '7'. But,\n    // it doesn't send a normal 'Connection: Upgrade' header. Instead it\n    // sends: 'Connection: keep-alive, Upgrade'. Brilliant.\n    String connectionHeader = request.getHeader(io.vertx.core.http.HttpHeaders.CONNECTION);\n    if (connectionHeader == null || !connectionHeader.toLowerCase().contains(\"upgrade\")) {\n      request.response()\n        .setStatusCode(BAD_REQUEST.code())\n        .end(\"\\\"Connection\\\" header must be \\\"Upgrade\\\".\");\n      throw new WebSocketHandshakeException(\"Invalid connection header\");\n    }\n    if (request.method() != io.vertx.core.http.HttpMethod.GET) {\n      request.response()\n        .setStatusCode(METHOD_NOT_ALLOWED.code())\n        .end();\n      throw new WebSocketHandshakeException(\"Invalid HTTP method\");\n    }\n    String wsURL;\n    try {\n      wsURL = HttpUtils.getWebSocketLocation(request, isSsl());\n    } catch (Exception e) {\n      request.response()\n        .setStatusCode(BAD_REQUEST.code())\n        .end(\"Invalid request URI\");\n      throw new WebSocketHandshakeException(\"Invalid WebSocket location\", e);\n    }\n    String subProtocols = null;\n    if (webSocketConfig.getSubProtocols() != null) {\n      subProtocols = String.join(\",\", webSocketConfig.getSubProtocols());\n    }\n    WebSocketDecoderConfig config = WebSocketDecoderConfig.newBuilder()\n      .allowExtensions(webSocketConfig.getUsePerMessageCompression() || webSocketConfig.getUsePerFrameCompression())\n      .maxFramePayloadLength(webSocketConfig.getMaxFrameSize())\n      .allowMaskMismatch(webSocketConfig.isUseUnmaskedFrames())","sourceCodeStart":363,"sourceCodeEnd":399,"githubUrl":"https://github.com/eclipse-vertx/vert.x/blob/fb308bd8c3f12c79f4ae89bef67fadf6c80d036e/vertx-core/src/main/java/io/vertx/core/http/impl/http1/Http1ServerConnection.java#L363-L399","documentation":"This WebSocketHandshakeException is thrown in createHandshaker when the WebSocket upgrade request uses an HTTP method other than GET. RFC 6455 mandates that the opening handshake be a GET request. Vert.x responds with 405 Method Not Allowed and aborts the handshake.","triggerScenarios":"Issuing POST/PUT/DELETE (or any non-GET) request to a WebSocket endpoint and then calling the server-side upgrade path (createHandshaker, invoked from createWebSocket).","commonSituations":"Posting JSON to a URL that also serves WebSocket upgrades; misconfigured client libraries using POST; load tests sending POST requests to a websocket route.","solutions":["Send the WebSocket handshake as an HTTP GET request.","Fix client library configuration that overrides the handshake method.","Route non-GET traffic away from the WebSocket endpoint so it never reaches the upgrade handler.","If you need both REST and WebSocket on one URL, branch on request.method() before upgrading."],"exampleFix":"// before\nhttpClient.request(HttpMethod.POST, \"/ws\")\n  .compose(req -> req.send());\n\n// after (WebSocket handshake must be GET)\nclient.webSocket(\"/ws\");","handlingStrategy":"validation","validationCode":"if (request.method() != HttpMethod.GET) {\n  // WebSocket handshake must be GET; reject early\n}","typeGuard":null,"tryCatchPattern":"try {\n  serverRequest.toWebSocket();\n} catch (WebSocketHandshakeException e) {\n  respondMethodNotAllowed(e);\n}","preventionTips":["WebSocket handshakes are always GET per RFC 6455","Keep REST routes separate from WebSocket upgrade routes","Audit test suites hitting the WS endpoint with POST"],"tags":["websocket","http1","handshake","method-not-allowed"],"backgroundTag":"http-error-response","analyzedSha":"fb308bd8c3f12c79f4ae89bef67fadf6c80d036e","analyzedAt":"2026-09-06T11:37:12.241Z","contentChangedAt":"2026-09-06T11:37:12.241Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}