grafana/k6 · error
%w
Error message
%w
What it means
While spawning the browser process, k6 calls cmd.StdoutPipe(); if the OS refuses to create the pipe, the raw error is wrapped and returned. This is an environment-level failure before the browser even starts, almost always file-descriptor exhaustion (EMFILE) or a fork/resource limit.
Source
Thrown at internal/js/modules/k6/browser/common/browser_process.go:166
return p.meta.Cleanup() //nolint:wrapcheck
}
type command struct {
*exec.Cmd
done chan struct{}
stdout, stderr io.Reader
}
func execute(
ctx context.Context, path string, args []string,
dataDir *storage.Dir, logger *log.Logger,
) (command, error) {
cmd := exec.CommandContext(ctx, path, args...) //nolint:gosec
killAfterParent(cmd)
stdout, err := cmd.StdoutPipe()
if err != nil {
return command{}, fmt.Errorf("%w", err)
}
stderr, err := cmd.StderrPipe()
if err != nil {
return command{}, fmt.Errorf("%w", err)
}
// We must start the cmd before calling cmd.Wait, as otherwise the two
// can run into a data race.
err = cmd.Start()
if os.IsNotExist(err) { //nolint:forbidigo
return command{}, fmt.Errorf("file does not exist: %s", path)
}
if err != nil {
return command{}, fmt.Errorf("%w", err)
}
if ctx.Err() != nil {
return command{}, ContextErr(ctx)
}View on GitHub (pinned to 93accf6570)
Solutions
- Check the limit with ulimit -n and raise it (e.g. ulimit -n 4096 or the systemd/containers equivalent).
- Kill orphaned chrome/chromium processes from earlier failed runs before starting the test.
- Reduce the number of parallel browser VUs (scenario vus/maxVUs) to lower simultaneous process spawns.
Example fix
# before ulimit -n 1024 k6 run browser-test.js # fails with wrapped pipe error # after ulimit -n 8192 k6 run browser-test.js
Defensive patterns
Strategy: validation
Validate before calling
# fail fast if the fd limit is too low for parallel browser VUs OPEN=$(ulimit -n) if [ "$OPEN" -lt 2048 ]; then echo "open-file limit $OPEN is too low for browser scenarios" >&2; exit 1 fi
Prevention
- Set ulimit -n (or container --ulimit nofile) explicitly in run environments.
- Clean up orphaned chromium processes between runs (pkill -f 'chrome.*user-data-dir' or dedicated user-data dirs).
- Cap concurrent browser VUs to keep descriptor usage bounded.
When it happens
Trigger: Launching a browser when the k6 process has hit its open-file limit (ulimit -n) — typically with many concurrent VUs each spawning a browser and websocket connections.
Common situations: High concurrency browser scenarios on CI runners with low default ulimits; leaking chrome processes from previous crashed runs; long soak tests accumulating descriptors.
Related errors
- browser process ended unexpectedly
- influxdb's ConcurrentWrites must be a positive number
- 105
- context is done before all '%s' events were processed
- launching browser: %w
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/0eafc413f9abd9db.
Report an issue: GitHub.