{"record":{"id":"df6ad35e7653b278","repo":"hashicorp/nomad","slug":"failed-to-upgrade-connection-v","errorCode":null,"errorMessage":"failed to upgrade connection: %v","messagePattern":"failed to upgrade connection: (.+?)","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"command/agent/websockets.go","lineNumber":60,"sourceCode":"// already-upgraded connection to the handler. We pass the connection and the\n// auth token via request context.\n//\n// NOTE: Outside of initial setup/upgrade failures, this handler should not\n// return any value or error after the connection has been upgraded to a\n// websocket. Any value or error should be sent to the websocket connection\n// along with a close message before returning.\nfunc (s *HTTPServer) wrapWebsocketHandler(handler handlerFn) handlerFn {\n\treturn func(w http.ResponseWriter, req *http.Request) (any, error) {\n\n\t\tif fips140.Enabled() {\n\t\t\treturn \"\", fmt.Errorf(\"websockets are disallowed in FIPS-140 mode\")\n\t\t}\n\n\t\t// Upgrade the connection\n\t\tconn, err := s.wsUpgrader.Upgrade(w, req, nil)\n\t\tif err != nil {\n\t\t\t// The upgrade failed so return the error.\n\t\t\treturn nil, fmt.Errorf(\"failed to upgrade connection: %v\", err)\n\t\t}\n\n\t\t// Ensure the underlying websocket connection is closed when we\n\t\t// are done. This does not transmit the close message to the\n\t\t// client, so that must still be done before returning from\n\t\t// this function. Failure to send the close message can cause\n\t\t// the client connection to hang for an extended period of time\n\t\t// before closing.\n\t\tdefer conn.Close()\n\n\t\ttoken, err := s.readWsHandshake(conn.ReadJSON, req)\n\t\tif err != nil {\n\t\t\tconn.WriteMessage(websocket.CloseMessage,\n\t\t\t\twebsocket.FormatCloseMessage(toWsCode(400), err.Error()))\n\t\t\treturn nil, nil\n\t\t}\n\n\t\t// Store connection and token in context for handler to use","sourceCodeStart":42,"sourceCodeEnd":78,"githubUrl":"https://github.com/hashicorp/nomad/blob/482b49bf1aec006f089bcfc7e632d8f6ac303e5e/command/agent/websockets.go#L42-L78","documentation":"Returned by wrapWebsocketHandler when the HTTP-to-websocket upgrade performed before handing off to the wrapped handler fails (e.g. missing/bad Upgrade headers or underlying hijack error); the connection is never upgraded so the handler cannot run.","triggerScenarios":"s.wsUpgrader.Upgrade(w, req, nil) fails because the request lacks a valid Upgrade: websocket header, the Sec-WebSocket-Key is missing/invalid, the Origin fails the CheckOrigin policy, or the client sent an incompatible websocket version.","commonSituations":"Proxy/load balancer stripping Upgrade/Connection headers, browser sending an unexpected Origin, an HTTP/2-only client, or a client library not performing the handshake correctly.","solutions":["Ensure any proxy in front of Nomad passes the Upgrade and Connection headers (e.g. nginx 'proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection \"upgrade\"').","Check the wrapped error text for 'websocket: the client is not using the websocket protocol' vs origin rejection and fix client headers accordingly.","Use the correct client library (nomad websocket exec/logs endpoints with proper Sec-WebSocket-* headers).","Verify Origin against the server's wsUpgrader CheckOrigin configuration."],"exampleFix":"// before (nginx)\nproxy_pass http://nomad;\n// after (nginx)\nproxy_http_version 1.1;\nproxy_set_header Upgrade $http_upgrade;\nproxy_set_header Connection \"upgrade\";\nproxy_pass http://nomad;","handlingStrategy":"try-catch","validationCode":"u, _ := url.Parse(wsURL)\nif u.Scheme != \"ws\" && u.Scheme != \"wss\" {\n    return fmt.Errorf(\"expected ws(s) URL, got %s\", u.Scheme)\n}\nconn, resp, err := websocket.DefaultDialer.Dial(wsURL, nil)\nif err != nil && resp != nil { return fmt.Errorf(\"handshake: %d %s\", resp.StatusCode, err) }","typeGuard":null,"tryCatchPattern":"conn, _, err := dialer.Dial(wsURL, nil)\nif err != nil {\n    log.Printf(\"ws upgrade failed (check proxy Upgrade headers / Origin): %v\", err)\n    return err\n}","preventionTips":["Configure reverse proxies to forward Upgrade/Connection headers.","Keep client websocket versions HTTP/1.1 (no h2c websocket).","Match Origin against the server's CheckOrigin policy.","Test with a direct connection to the agent to isolate proxy issues."],"tags":["websocket","http-upgrade","proxy","network"],"backgroundTag":"websocket-handshake-failed","analyzedSha":"482b49bf1aec006f089bcfc7e632d8f6ac303e5e","analyzedAt":"2026-09-04T07:54:14.808Z","contentChangedAt":"2026-09-04T07:54:14.808Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}