grafana/k6 · error

browser process ended unexpectedly

Error message

browser process ended unexpectedly

What it means

When launching a local browser, k6 starts the Chrome process, parses its stderr for the DevTools WebSocket URL, and watches the process. If the process's done channel fires before a URL was parsed, the browser died during startup — the parse result is discarded and 'browser process ended unexpectedly' is returned. It is the catch-all for Chrome crashing immediately on launch.

Source

Thrown at internal/js/modules/k6/browser/common/browser_process.go:225

// it. If the process ends abruptly, it will return the first error from stderr.
func parseDevToolsURL(ctx context.Context, cmd command) (_ string, err error) {
	parser := &devToolsURLParser{
		sc: bufio.NewScanner(cmd.stderr),
	}
	done := make(chan struct{})
	go func() {
		for parser.scan() {
		}
		close(done)
	}()
	for err == nil {
		select {
		case <-done:
			err = parser.err()
		case <-ctx.Done():
			err = ContextErr(ctx)
		case <-cmd.done:
			err = errors.New("browser process ended unexpectedly")
		}
	}
	if parser.url != "" {
		err = nil
	}

	return parser.url, err
}

type devToolsURLParser struct {
	sc *bufio.Scanner

	errs []error
	url  string
}

func (p *devToolsURLParser) scan() bool {
	if !p.sc.Scan() {

View on GitHub (pinned to 93accf6570)

Solutions

  1. Reproduce outside k6 to see the real stderr: run the exact binary with your flags, e.g. google-chrome --headless=new --no-sandbox --dump-dom about:blank — install whatever libraries it complains about
  2. When running as root (containers/CI), pass --no-sandbox: K6_BROWSER_ARGS='--no-sandbox' or args in browser options
  3. Verify the executable is a genuine Chrome/Chromium binary for this architecture (file /usr/bin/chromium)
  4. Or skip local launch entirely: K6_BROWSER_WS_ENDPOINT=ws://host:9222/... against an already-running browser

Example fix

# before (root container, missing deps)
RUN apk add --no-cache k6

# after
RUN apk add --no-cache k6 chromium nss freetype freetype-dev harfbuzz ca-certificates ttf-liberation
ENV K6_BROWSER_EXECUTABLE_PATH=/usr/bin/chromium-browser \
    K6_BROWSER_ARGS="--no-sandbox"
Defensive patterns

Strategy: validation

Validate before calling

#!/bin/sh
# Validate the browser launches with the same flags k6 will use before running tests
BIN="${K6_BROWSER_EXECUTABLE_PATH:-$(command -v google-chrome || command -v chromium)}"
[ -n "$BIN" ] || { echo 'no browser binary found' >&2; exit 1; }
exec "$BIN" --headless=new --no-sandbox --user-data-dir=/tmp/k6-preflight --dump-dom about:blank >/dev/null

Prevention

When it happens

Trigger: Chrome exits at startup: missing shared libraries in a slim container (libnss3, libgbm, libatk...); running as root without --no-sandbox; incompatible flags passed via args/K6_BROWSER_ARGUMENTS; wrong-architecture or broken binary; the data dir being unwritable.

Common situations: Minimal Docker images without chromium dependencies; CI running as root; custom Chrome flags copied from Playwright configs; snap-packaged Chromium on Ubuntu; disk-full or read-only profiles.

Related errors


AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15). Data as JSON: /api/errors/99ad0b30c7ae37e0. Report an issue: GitHub.