{"record":{"id":"f44c11ebb3428a7d","repo":"nats-io/nats-server","slug":"s-websocket-handshake-error-s","errorCode":null,"errorMessage":"%s - websocket handshake error: %s","messagePattern":"(.+?) - websocket handshake error: (.+?)","errorType":"http","errorClass":null,"httpStatus":null,"severity":"error","filePath":"server/websocket.go","lineNumber":1023,"sourceCode":"\t\t\t\t\t\t} else if strings.EqualFold(p, wsPMCCliNoCtx) {\n\t\t\t\t\t\t\tcnc = true\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif snc && cnc {\n\t\t\t\t\t\t\treturn true, true\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn true, false\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn false, false\n}\n\n// Send an HTTP error with the given `status` to the given http response writer `w`.\n// Return an error created based on the `reason` string.\nfunc wsReturnHTTPError(w http.ResponseWriter, r *http.Request, status int, reason string) error {\n\terr := fmt.Errorf(\"%s - websocket handshake error: %s\", r.RemoteAddr, reason)\n\tw.Header().Set(\"Sec-Websocket-Version\", \"13\")\n\thttp.Error(w, http.StatusText(status), status)\n\treturn err\n}\n\n// If the server is configured to accept any origin, then this function returns\n// `nil` without checking if the Origin is present and valid. This is also\n// the case if the request does not have the Origin header.\n// Otherwise, this will check that the Origin matches the same origin or\n// any origin in the allowed list.\nfunc (w *srvWebsocket) checkOrigin(r *http.Request) error {\n\tw.mu.RLock()\n\tcheckSame := w.sameOrigin\n\tlistEmpty := len(w.allowedOrigins) == 0\n\tw.mu.RUnlock()\n\tif !checkSame && listEmpty {\n\t\treturn nil\n\t}","sourceCodeStart":1005,"sourceCodeEnd":1041,"githubUrl":"https://github.com/nats-io/nats-server/blob/3a66a489d262bf89b71a71c955c94920394532f3/server/websocket.go#L1005-L1041","documentation":"Created by wsReturnHTTPError() when a websocket upgrade request fails validation. It combines the client's RemoteAddr with a specific rejection reason (bad method, missing/invalid Sec-WebSocket headers, bad version, etc.), sends the corresponding HTTP error response, and is returned to the caller to log. It denotes a malformed or unauthorized handshake, not a server fault.","triggerScenarios":"Thrown at server/websocket.go:1023 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Read the reason portion to identify which handshake requirement the client failed","Ensure the client sends a proper GET upgrade request with Sec-WebSocket-Key, Version: 13, and correct headers","If the client is trusted but blocked by auth/origin checks, adjust server websocket options (allowed origins, users, TLS)"],"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"}