grafana/k6 · error
connecting to browser: %w
Error message
connecting to browser: %w
What it means
Returned by BrowserType.connect when link() cannot establish the remote browser process: common.NewRemoteBrowserProcess fails to dial the WebSocket endpoint, so browserProc is nil and the dial error is wrapped as 'connecting to browser'. Callers of Connect/ConnectOverCDP additionally wrap it in k6ext.UserFriendlyError, which hints at timeout causes. This is the generic 'cannot reach the remote Chrome over CDP' failure.
Source
Thrown at internal/js/modules/k6/browser/chromium/browser_type.go:210
bp, err := b.connect(ctx, vuCtx, wsEndpoint, browserOpts, logger)
if err != nil {
err = &k6ext.UserFriendlyError{
Err: err,
Timeout: browserOpts.Timeout,
}
return nil, fmt.Errorf("%w", err)
}
return bp, nil
}
func (b *BrowserType) connect(
ctx, vuCtx context.Context, wsURL string, opts *common.BrowserOptions, logger *log.Logger,
) (*common.Browser, error) {
browserProc, err := b.link(ctx, wsURL, logger)
if browserProc == nil {
return nil, fmt.Errorf("connecting to browser: %w", err)
}
// If this context is cancelled we'll initiate an extension wide
// cancellation and shutdown.
browserCtx, browserCtxCancel := context.WithCancel(vuCtx)
b.Ctx = browserCtx
browser, err := common.NewBrowser(
ctx, browserCtx, browserCtxCancel, browserProc, opts, logger,
)
if err != nil {
return nil, fmt.Errorf("connecting to browser: %w", err)
}
return browser, nil
}
func (b *BrowserType) link(
ctx context.Context,View on GitHub (pinned to 93accf6570)
Solutions
- Verify the browser is reachable: curl http://<host>:<port>/json/version from the same host/container k6 runs on
- If the error mentions timeout, raise K6_BROWSER_TIMEOUT (e.g. export K6_BROWSER_TIMEOUT=60s) for slow remote setups
- Ensure Chrome was started with --remote-debugging-port=<port> and, for remote/non-localhost setups, the appropriate --remote-debugging-address
- Match the scheme to the transport: wss:// for TLS endpoints, ws:// for plain
- Add a readiness wait/retry loop around connectOverCDP when the browser container starts in parallel with the test
Example fix
// before
const browser = chromium.connectOverCDP('ws://browserless:3000');
// after
let browser;
for (let i = 0; i < 5; i++) {
try { browser = chromium.connectOverCDP('ws://browserless:3000'); break; }
catch (e) { sleep(3); }
}
if (!browser) throw new Error('browser not reachable after retries'); Defensive patterns
Strategy: retry
Validate before calling
// Pre-flight the browser's HTTP endpoint before dialing the WS one
import http from 'k6/http';
function browserReady(host, port, timeoutMs = 30000) {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
const r = http.get(`http://${host}:${port}/json/version`, { timeout: '2s' });
if (r.status === 200) return r.json('webSocketDebuggerUrl');
sleep(2);
}
throw new Error(`browser at ${host}:${port} not ready`);
}
const wsUrl = browserReady(__ENV.BROWSER_HOST, __ENV.BROWSER_PORT); Try / catch
let browser;
for (let attempt = 0; attempt < 3; attempt++) {
try {
browser = chromium.connectOverCDP(wsUrl);
break;
} catch (e) {
const m = String(e.message);
if (attempt < 2 && (m.includes('connecting to browser') || m.includes('timed out'))) {
sleep(3);
continue;
}
throw e;
}
} Prevention
- Gate the test on a readiness probe of /json/version before connecting
- Set K6_BROWSER_TIMEOUT high enough for remote/containerized browsers
- Ensure Chrome is started with --remote-debugging-port and reachable from the k6 network
When it happens
Trigger: chromium.connect()/connectOverCDP() to an endpoint where Chrome is not listening (wrong port, process not started); firewall or network partition between k6 and the remote browser; endpoint requires auth/TLS and the handshake is rejected; the remote Chrome exited between discovery and connect; dial exceeds K6_BROWSER_TIMEOUT.
Common situations: Remote browser container (e.g. browserless/chrome) not ready yet when the test starts; k8s Service name typo; connecting to a ws:// endpoint served only over TLS (needs wss://); Chrome started without --remote-debugging-port; UserFriendlyError text pointing at a too-small K6_BROWSER_TIMEOUT on slow CI machines.
Related errors
- connecting to browser DevTools URL: %w
- WebSocket endpoint cannot be empty
- errorText
- failed to dial: %w
- connecting to Chromium over CDP: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/c068f20e1cc61f26.
Report an issue: GitHub.