{"record":{"id":"9e7cc147f2265538","repo":"netbirdio/netbird","slug":"websocket-connection-failed","errorCode":null,"errorMessage":"WebSocket connection failed","messagePattern":"WebSocket connection failed","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"util/wsproxy/constants.go","lineNumber":18,"sourceCode":"package wsproxy\n\nimport \"errors\"\n\n// ProxyPath is the base path where the WebSocket proxy is mounted on servers.\nconst ProxyPath = \"/ws-proxy\"\n\n// Component paths that are appended to ProxyPath\nconst (\n\tManagementComponent = \"/management\"\n\tSignalComponent     = \"/signal\"\n\tFlowComponent       = \"/flow\"\n)\n\n// Common errors\nvar (\n\tErrConnectionTimeout  = errors.New(\"WebSocket connection timeout\")\n\tErrConnectionFailed   = errors.New(\"WebSocket connection failed\")\n\tErrBackendUnavailable = errors.New(\"backend unavailable\")\n)\n","sourceCodeStart":1,"sourceCodeEnd":21,"githubUrl":"https://github.com/netbirdio/netbird/blob/93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c/util/wsproxy/constants.go#L1-L21","documentation":"Sentinel error from the browser/WASM gRPC dialer. The JavaScript WebSocket's onerror handler pushes this error into the dialer's channel, and WithWebSocketDialer returns it instead of a connection. It fires when the browser itself fails the connection (refused, TLS failure, mixed content) rather than timing out.","triggerScenarios":"Connection refused because the host/port is down; TLS error on wss (untrusted or mismatched certificate); mixed-content blocking when an https page opens a ws:// URL; DNS resolution failure in the browser.","commonSituations":"Serving the WASM app over https while the WebSocket proxy is plain ws; self-signed certificate not trusted by the browser; corporate proxy stripping the WebSocket upgrade.","solutions":["Confirm scheme and host: wss for TLS-enabled setups, and that the target serves the /ws-proxy path.","Ensure the page's origin is compatible (no https -> ws mixed content).","Open the WebSocket URL in the browser devtools console to see the underlying browser error, then fix the proxy or certificate accordingly."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isWsDialFailed(err error) bool {\n    return errors.Is(err, wsproxy.ErrConnectionFailed)\n}","tryCatchPattern":"conn, err := dialer(ctx)\nif err != nil {\n    if errors.Is(err, wsproxy.ErrConnectionFailed) {\n        // browser refused the WebSocket: TLS/mixed-content/host issue.\n        // Retry a couple of times, then fail with guidance to check the URL scheme and proxy\n    }\n    return err\n}","preventionTips":["Never mix https pages with ws:// endpoints; browsers block the upgrade as mixed content.","Test the WebSocket URL directly in browser devtools before debugging the gRPC layer.","Make scheme selection (ws/wss) explicit configuration rather than a guess from the page origin."],"tags":["websocket","wasm","grpc","network","browser","tls"],"backgroundTag":null,"analyzedSha":"93e97f4bf1ad715072dcb3fb6cdb1763431b5a9c","analyzedAt":"2026-08-16T03:09:19.136Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}