grafana/k6 · error
WebSocket endpoint cannot be empty
Error message
WebSocket endpoint cannot be empty
What it means
Before k6 attaches to an existing browser over CDP, validateWSEndpoint sanity-checks the WebSocket URL: it must be non-empty after trimming, parse as a URL, and use the ws:// or wss:// scheme (other failures give their own messages). This specific error means the wsEndpoint value resolved to an empty or whitespace-only string, so connecting would be meaningless.
Source
Thrown at internal/js/modules/k6/browser/chromium/browser_type.go:155
bp, err := b.connect(ctx, ctx, wsEndpoint, browserOpts, logger)
if err != nil {
err = &k6ext.UserFriendlyError{
Err: err,
Timeout: browserOpts.Timeout,
}
return nil, fmt.Errorf("%w", err)
}
return bp, nil
}
// validateWSEndpoint returns an error if wsEndpoint is not a usable CDP
// WebSocket URL, catching common mistakes (an empty value, a non-ws scheme,
// a missing host, etc.) before we attempt to connect.
func validateWSEndpoint(wsEndpoint string) error {
if strings.TrimSpace(wsEndpoint) == "" {
return errors.New("WebSocket endpoint cannot be empty")
}
u, err := url.Parse(wsEndpoint)
if err != nil {
return fmt.Errorf("invalid WebSocket endpoint %q: %w", wsEndpoint, err)
}
if u.Scheme != "ws" && u.Scheme != "wss" {
return fmt.Errorf(
"invalid WebSocket endpoint %q: scheme must be ws or wss, got %q", wsEndpoint, u.Scheme,
)
}
if u.Hostname() == "" {
return fmt.Errorf("invalid WebSocket endpoint %q: host is missing", wsEndpoint)
}
return nilView on GitHub (pinned to 93accf6570)
Solutions
- Set a real CDP WebSocket endpoint: K6_BROWSER_WS_ENDPOINT=ws://localhost:9222/devtools/browser/<id> — get the id from curl http://localhost:9222/json/version when Chrome runs with --remote-debugging-port=9222
- Make sure the variable is exported in the same shell/step that runs k6 (print it masked in CI logs to confirm it is set)
- Trim accidental whitespace/quotes in the value; a quoted value with stray spaces trips the trim check
Example fix
# before export K6_BROWSER_WS_ENDPOINT="" k6 run script.js # after google-chrome --remote-debugging-port=9222 & export K6_BROWSER_WS_ENDPOINT="$(curl -s http://localhost:9222/json/version | jq -r .webSocketDebuggerUrl)" k6 run script.js
Defensive patterns
Strategy: validation
Validate before calling
const endpoint = (process.env.K6_BROWSER_WS_ENDPOINT ?? '').trim();
if (!endpoint) {
throw new Error('K6_BROWSER_WS_ENDPOINT is empty — start Chrome with --remote-debugging-port and set the ws URL');
}
if (!/^wss?:\/\//.test(endpoint)) {
throw new Error('K6_BROWSER_WS_ENDPOINT must start with ws:// or wss://');
} Prevention
- Fetch the endpoint programmatically: curl http://localhost:9222/json/version gives webSocketDebuggerUrl
- Assert required env vars in a CI preflight step before invoking k6
- Avoid empty-string defaults for the env var in compose/CI templates
When it happens
Trigger: Setting K6_BROWSER_WS_ENDPOINT to an empty value or spaces; building the endpoint from an env var that is not set in this shell/CI step (expands to empty); copying a config template where the endpoint placeholder was never filled in.
Common situations: CI pipelines where the env var is defined in one job but used in another; docker-compose/service definitions with empty-string defaults; scripts that export the endpoint conditionally and skip it on some branches.
Related errors
- k6 couldn't detect google chrome or a chromium-supported bro
- connecting to Chromium over CDP: %w
- sending a message to browser: %w
- updating extra HTTP headers: %w
- both K6_CLOUD_METRICS_PUSH_URL and K6_CLOUD_TEST_RUN_TOKEN m
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/20375e15a7ad9f9f.
Report an issue: GitHub.