grafana/k6 · critical
failed to dial websocket at %s: %w
Error message
failed to dial websocket at %s: %w
What it means
Connection dialing (websocket.Dialer.DialContext) to the DevTools wsURL failed, so k6 cancels the connection context with this cause while returning the raw dial error. The %s is the exact websocket URL attempted (local browser endpoint or a K6_BROWSER_REMOTE_URL).
Source
Thrown at internal/js/modules/k6/browser/common/connection.go:169
var tlsConfig *tls.Config
wsd := websocket.Dialer{
HandshakeTimeout: time.Second * 60,
Proxy: http.ProxyFromEnvironment, // TODO(fix): use proxy settings from launch options
TLSClientConfig: tlsConfig,
WriteBufferSize: wsWriteBufferSize,
ReadBufferSize: wsWriteBufferSize,
}
ctx, cancelCtx := context.WithCancelCause(ctx)
conn, response, connErr := wsd.DialContext(ctx, wsURL, header)
if response != nil {
defer func() {
_ = response.Body.Close()
}()
}
if connErr != nil {
cancelCtx(fmt.Errorf("failed to dial websocket at %s: %w", wsURL, connErr))
return nil, connErr
}
c := Connection{
BaseEventEmitter: NewBaseEventEmitter(ctx),
ctx: ctx,
cancelCtx: cancelCtx,
wsURL: wsURL,
logger: logger,
conn: conn,
sendCh: make(chan *cdproto.Message, 32), // Avoid blocking in Execute
recvCh: make(chan *cdproto.Message),
closeCh: make(chan int),
errorCh: make(chan error),
done: make(chan struct{}),
closing: make(chan struct{}),
msgIDGen: &msgID{},
sessions: make(map[target.SessionID]*Session),View on GitHub (pinned to 93accf6570)
Solutions
- Verify the exact URL from the message: curl http://host:port/json/version must return the webSocketDebuggerUrl.
- Ensure the remote browser is launched with --remote-debugging-port=<port> and is reachable (telnet/nc).
- Use the full ws:// URL including the /devtools/browser/... path, not just host:port.
- Open the port in firewall/NetworkPolicy rules and bypass ws-blocking proxies.
- If the remote is started as part of the pipeline, wait for its readiness probe before launching k6.
Example fix
# before export K6_BROWSER_REMOTE_URL=ws://browser:3000 k6 run test.js # failed to dial websocket # after # browser service exposes 9222 and is ready curl http://browser:9222/json/version # returns webSocketDebuggerUrl export K6_BROWSER_REMOTE_URL=ws://browser:9222/devtools/browser/<id> k6 run test.js
Defensive patterns
Strategy: retry
Validate before calling
# before starting k6, confirm the remote browser answers and grab a fresh ws URL
BASE="${K6_BROWSER_REMOTE_URL%%/devtools/*}"
BASE="${BASE#ws://}"; BASE="${BASE#http://}"
WS=$(curl -fsS "http://$BASE/json/version" | sed -n 's/.*"webSocketDebuggerUrl": *"\([^"]*\)".*/\1/p')
[ -n "$WS" ] || { echo "remote browser not reachable at $BASE" >&2; exit 1; }
export K6_BROWSER_REMOTE_URL="$WS" Try / catch
try {
await browser.newPage();
} catch (e) {
if (/failed to dial websocket/.test(String(e))) {
// remote browser not ready — surface a clear remediation instead of a raw dial error
throw new Error('Remote browser unreachable: verify it runs with --remote-debugging-port and the URL is ws://host:port/devtools/browser/<id>');
}
throw e;
} Prevention
- Always health-check the remote browser (/json/version) before launching k6 against it.
- Use readiness probes when the remote browser starts in the same pipeline.
- Keep LB/proxy idle timeouts above the test duration so ws connections are not reaped.
When it happens
Trigger: Connecting to a remote browser (K6_BROWSER_REMOTE_URL) that is not running, not listening on that port, firewalled, or requires auth; the locally launched browser's DevTools endpoint dying between discovery and dial; a proxy interfering with ws:// upgrades.
Common situations: Wrong or stale K6_BROWSER_REMOTE_URL (http:// vs ws://, missing /devtools/browser/<id> path); remote Chrome not started with --remote-debugging-port; k8s NetworkPolicy or corporate firewall blocking the port; remote browser started per-test but k6 dialing before it is ready.
Related errors
- WebSocket endpoint cannot be empty
- missing presigned url in response body
- unexpected HTTP error from %s: %d %s
- couldn't parse cloud logs host %w
- connecting to Chromium over CDP: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/c58f4f12f91c39be.
Report an issue: GitHub.