txthinking/brook · error
string(b)
Error message
string(b)
What it means
WebSocketDial performs a WebSocket handshake and expects 'HTTP/1.1 101 Switching Protocols'. If the response starts with 'HTTP/1.1 ' but does not contain '101', the server refused the upgrade; the connection is closed and the full response is returned as the error message. The raw response is surfaced so the caller can see the server's status/reason.
Source
Thrown at websocket.go:156
if _, err := c.Write(b); err != nil {
c.Close()
return nil, err
}
r := bufio.NewReader(c)
for {
b, err = r.ReadBytes('\n')
if err != nil {
c.Close()
return nil, err
}
b = bytes.TrimSpace(b)
if len(b) == 0 {
break
}
if bytes.HasPrefix(b, []byte("HTTP/1.1 ")) {
if !bytes.Contains(b, []byte("101")) {
c.Close()
return nil, errors.New(string(b))
}
}
if bytes.HasPrefix(b, []byte("Sec-WebSocket-Accept: ")) {
h := sha1.New()
h.Write([]byte(k))
h.Write([]byte("258EAFA5-E914-47DA-95CA-C5AB0DC85B11"))
ak := base64.StdEncoding.EncodeToString(h.Sum(nil))
if string(b[len("Sec-WebSocket-Accept: "):]) != ak {
c.Close()
return nil, errors.New(string(b))
}
}
}
return c, nil
}
type TLSFragmentConn struct {
net.ConnView on GitHub (pinned to 5cd13ef3b1)
Solutions
- Read the error message (it contains the full HTTP response) to identify the returned status code and fix accordingly
- Verify the WebSocket path, host and port are correct
- Ensure any required auth handshake with the server completed before dialing
- Bypass or correctly configure reverse proxies/CDNs to pass the Upgrade and Connection headers
- Confirm the server actually implements the WebSocket protocol on that endpoint
Example fix
// before: dialing plain server path with a WebSocket dialer
c, err := WebSocketDial("wss://host/plain-endpoint")
// after: use the endpoint that speaks WebSocket
c, err := WebSocketDial("wss://host/ws") Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-check the endpoint accepts upgrades:
resp, err := http.Get(endpoint)
if err == nil && resp.StatusCode != http.StatusSwitchingProtocols { /* endpoint wrong */ } Try / catch
c, err := WebSocketDial(url)
if err != nil {
if strings.Contains(err.Error(), "401") || strings.Contains(err.Error(), "403") {
// refresh auth, then retry
} else if strings.Contains(err.Error(), "404") {
// fix endpoint path
}
return err
} Prevention
- Verify the path/port actually serves WebSocket
- Complete any required auth handshake first
- Configure proxies to pass Upgrade/Connection headers
When it happens
Trigger: Calling WebSocketDial (directly or via CreateExchanger/TCPHandle/UDPHandle) when the WebSocket server replies with a non-101 HTTP/1.1 status - e.g. 404 on a wrong path, 401/403 auth rejected, 426 upgrade required, or 502 from an intermediary.
Common situations: Wrong WebSocket endpoint path or port; missing/expired auth accepted by an auth gateway in front of the socket; server not actually supporting WebSocket; a reverse proxy (nginx/CDN) blocking the Upgrade; target behind a captive portal returning an HTML error page.
Related errors
AI-assisted analysis of txthinking/brook@5cd13ef3b1 (2026-09-06).
Data as JSON: /api/errors/f018e6c3d733cd33.
Report an issue: GitHub.