{"record":{"id":"786297b9cf0850ea","repo":"nats-io/nats-server","slug":"invalid-websocket-connection","errorCode":null,"errorMessage":"invalid websocket connection","messagePattern":"invalid websocket connection","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/leafnode.go","lineNumber":3677,"sourceCode":"\tif noMasking {\n\t\treq.Header.Add(wsNoMaskingHeader, wsNoMaskingValue)\n\t}\n\tc.nc.SetDeadline(time.Now().Add(infoTimeout))\n\tif err := req.Write(c.nc); err != nil {\n\t\treturn nil, WriteError, err\n\t}\n\n\tvar resp *http.Response\n\n\tbr := bufio.NewReaderSize(c.nc, MAX_CONTROL_LINE_SIZE)\n\tresp, err = http.ReadResponse(br, req)\n\tif err == nil &&\n\t\t(resp.StatusCode != 101 ||\n\t\t\t!strings.EqualFold(resp.Header.Get(\"Upgrade\"), \"websocket\") ||\n\t\t\t!strings.EqualFold(resp.Header.Get(\"Connection\"), \"upgrade\") ||\n\t\t\tresp.Header.Get(\"Sec-Websocket-Accept\") != wsAcceptKey(wsKey)) {\n\n\t\terr = fmt.Errorf(\"invalid websocket connection\")\n\t}\n\t// Check compression extension...\n\tif err == nil && c.ws.compress {\n\t\t// Check that not only permessage-deflate extension is present, but that\n\t\t// we also have server and client no context take over.\n\t\tsrvCompress, noCtxTakeover := wsPMCExtensionSupport(resp.Header, false)\n\n\t\t// If server does not support compression, then simply disable it in our side.\n\t\tif !srvCompress {\n\t\t\tc.ws.compress = false\n\t\t} else if !noCtxTakeover {\n\t\t\terr = fmt.Errorf(\"compression negotiation error\")\n\t\t}\n\t}\n\t// Same for no masking...\n\tif err == nil && noMasking {\n\t\t// Check if server accepts no masking\n\t\tif resp.Header.Get(wsNoMaskingHeader) != wsNoMaskingValue {","sourceCodeStart":3659,"sourceCodeEnd":3695,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/leafnode.go#L3659-L3695","documentation":"Set during the leaf-node WebSocket client handshake when the HTTP response is not a valid 101 Switching Protocols upgrade: wrong status code, missing Upgrade/Connection headers, or a Sec-Websocket-Accept key that does not match wsAcceptKey(wsKey). It means the remote endpoint did not complete the WebSocket handshake correctly.","triggerScenarios":"Thrown at server/leafnode.go:3677 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Confirm the leaf node URL actually points to a WebSocket-enabled leaf node port","Check for intermediaries (proxies, load balancers) that strip Upgrade headers","Verify the server supports WebSockets on that port and shares the same accept-key logic"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3a66a489d262bf89b71a71c955c94920394532f3","analyzedAt":"2026-09-02T04:41:54.247Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}