netbirdio/netbird · error
WebSocket connection timeout
Error message
WebSocket connection timeout
What it means
Sentinel error from the browser/WASM gRPC dialer (util/wsproxy/client/dialer_js.go). WithWebSocketDialer opens a JavaScript WebSocket to ws(s)://<host>/ws-proxy/<component> and waits for the onopen event; if it does not fire within the 30-second dialTimeout, the socket is closed and this error is returned to the gRPC dialer.
Source
Thrown at util/wsproxy/constants.go:17
package wsproxy
import "errors"
// ProxyPath is the base path where the WebSocket proxy is mounted on servers.
const ProxyPath = "/ws-proxy"
// Component paths that are appended to ProxyPath
const (
ManagementComponent = "/management"
SignalComponent = "/signal"
FlowComponent = "/flow"
)
// Common errors
var (
ErrConnectionTimeout = errors.New("WebSocket connection timeout")
ErrConnectionFailed = errors.New("WebSocket connection failed")
ErrBackendUnavailable = errors.New("backend unavailable")
)
View on GitHub (pinned to 93e97f4bf1)
Solutions
- Verify the ws-proxy path and component suffix exist and the proxy upgrades WebSocket connections.
- Check TLS validity: the browser must trust the certificate for wss URLs.
- If the handshake is legitimately slow, raise the dialTimeout constant in dialer_js.go and rebuild the WASM client.
Defensive patterns
Strategy: retry
Type guard
func isWsDialTimeout(err error) bool {
return errors.Is(err, wsproxy.ErrConnectionTimeout)
} Try / catch
conn, err := dialer(ctx)
if err != nil {
if errors.Is(err, wsproxy.ErrConnectionTimeout) {
// handshake exceeded 30s: retry with backoff, then surface
// a user-actionable message (check proxy/TLS) after N attempts
}
return err
} Prevention
- Verify the /ws-proxy/<component> route and WebSocket upgrade in the reverse proxy before shipping.
- Ensure the browser trusts the certificate for wss URLs.
- Keep an eye on the 30s dialTimeout constant if deploying over high-latency links.
When it happens
Trigger: WASM client dialing a host that is unreachable or not serving WebSocket; the /ws-proxy/management|signal|flow route missing on the server; a TLS handshake that stalls (invalid cert, wrong scheme) for over 30 seconds.
Common situations: Reverse proxy in front of NetBird not forwarding the WebSocket upgrade; browser rejecting a self-signed certificate during wss; pointing the client at a plain-HTTP port with the wss scheme.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- WebSocket connection failed
- dial context: %w
- signal receive stream stalled
- upload debug bundle: %w
- failed to check SSO support: %v
AI-assisted analysis of netbirdio/netbird@93e97f4bf1 (2026-08-16).
Data as JSON: /api/errors/8232b2693c700cc8.
Report an issue: GitHub.