gofr-dev/gofr · error

Could not open WebSocket connection

Error message

Could not open WebSocket connection

What it means

The WebSocket middleware returns HTTP 400 with the body 'Could not open WebSocket connection' when gorilla's Upgrade() fails while handling an upgrade request. This happens when the request does not meet WebSocket handshake requirements or the underlying connection cannot be hijacked. It is an HTTP response, not a Go error value.

Source

Thrown at pkg/gofr/http/middleware/web_socket.go:21

import (
	"context"
	"net/http"

	gorillaWebsocket "github.com/gorilla/websocket"

	"gofr.dev/pkg/gofr/container"
	"gofr.dev/pkg/gofr/websocket"
)

// WSHandlerUpgrade middleware upgrades the incoming http request to a websocket connection using websocket upgrader.
func WSHandlerUpgrade(c *container.Container, wsManager *websocket.Manager) func(inner http.Handler) http.Handler {
	return func(inner http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			if gorillaWebsocket.IsWebSocketUpgrade(r) {
				conn, err := wsManager.WebSocketUpgrader.Upgrade(w, r, nil)
				if err != nil {
					c.Errorf("Failed to upgrade to WebSocket: %v", err)
					http.Error(w, "Could not open WebSocket connection", http.StatusBadRequest)

					return
				}

				// Add the connection to the hub
				wsManager.AddWebsocketConnection(r.Header.Get("Sec-WebSocket-Key"), &websocket.Connection{Conn: conn})

				// Store the websocket connection key in the context
				ctx := context.WithValue(r.Context(), websocket.WSConnectionKey, r.Header.Get("Sec-WebSocket-Key"))
				r = r.WithContext(ctx)
			}

			inner.ServeHTTP(w, r)
		})
	}
}

View on GitHub (pinned to 187eb24962)

Solutions

  1. Ensure the client sends a valid RFC 6455 handshake (Upgrade: websocket, Connection: Upgrade, Sec-WebSocket-Key, Sec-WebSocket-Version: 13)
  2. Serve the app over HTTP/1.1 and confirm the server/proxy supports connection upgrade; add proxy headers (e.g. proxy_set_header Upgrade/Connection in nginx)
  3. Check server logs for the 'Failed to upgrade to WebSocket: %v' line to see the underlying upgrade error

Example fix

// before (nginx)
location /ws { proxy_pass http://backend; }
// after (nginx)
location /ws {
  proxy_pass http://backend;
  proxy_http_version 1.1;
  proxy_set_header Upgrade $http_upgrade;
  proxy_set_header Connection "upgrade";
}
Defensive patterns

Strategy: try-catch

Validate before calling

if !gorillaWebsocket.IsWebSocketUpgrade(r) || r.Header.Get("Sec-WebSocket-Key") == "" || r.Header.Get("Sec-WebSocket-Version") != "13" { http.Error(w, "invalid handshake", http.StatusBadRequest); return }

Try / catch

conn, err := upgrader.Upgrade(w, r, nil)
if err != nil {
    logger.Errorf("upgrade failed: %v", err)
    http.Error(w, "Could not open WebSocket connection", http.StatusBadRequest)
    return
}

Prevention

When it happens

Trigger: Client sends a WebSocket upgrade request missing required headers (Sec-WebSocket-Key, Sec-WebSocket-Version, valid Upgrade/Connection); request passes through a proxy that strips headers; response headers already written (HTTP/2 or buffering) preventing connection hijack.

Common situations: Browsers/clients behind corporate proxies that mangle upgrade requests; serving WebSockets over HTTP/2 or through servers that don't support hijacking; ad-blocking proxies interfering with the handshake.

Related errors


AI-assisted analysis of gofr-dev/gofr@187eb24962 (2026-09-01). Data as JSON: /api/errors/7e5fd5c582740b73. Report an issue: GitHub.