grafana/k6 · error
couldn't parse cloud logs host %w
Error message
couldn't parse cloud logs host %w
What it means
Cloud log tailing (cloudapi/logs.go) opens a websocket to Config.LogsTailURL - default wss://cloudlogs.k6.io/api/v1/tail, overridable via K6_CLOUD_LOGS_TAIL_URL (cloudapi/config.go:30). Before connecting it url.Parse's the value; a parse failure aborts log tailing with this wrapped error. url.Parse only fails on structurally invalid URLs, so this almost always means a bad override value rather than a transient problem.
Source
Thrown at cloudapi/logs.go:91
}
return ts
}
func labelsToLogrusFields(labels map[string]string) logrus.Fields {
fields := make(logrus.Fields, len(labels))
for key, val := range labels {
fields[key] = val
}
return fields
}
func (c *Config) logtailConn(ctx context.Context, referenceID string, since time.Time) (*websocket.Conn, error) {
u, err := url.Parse(c.LogsTailURL.String)
if err != nil {
return nil, fmt.Errorf("couldn't parse cloud logs host %w", err)
}
u.RawQuery = fmt.Sprintf(`query={test_run_id="%s"}&start=%d`, referenceID, since.UnixNano())
headers := make(http.Header)
headers.Add("Authorization", "token "+c.Token.String)
headers.Add("X-K6testrun-Id", referenceID)
var conn *websocket.Conn
err = retry(sleeperFunc(time.Sleep), 3, 5*time.Second, 2*time.Minute, func() (err error) {
// We don't need to close the http body or use it for anything until we want to actually log
// what the server returned as body when it errors out
conn, _, err = websocket.DefaultDialer.DialContext(ctx, u.String(), headers) //nolint:bodyclose
return err
})
if err != nil {
return nil, err
}View on GitHub (pinned to 93accf6570)
Solutions
- Unset K6_CLOUD_LOGS_TAIL_URL to fall back to the default wss://cloudlogs.k6.io/api/v1/tail
- Fix the value to a full absolute URL with scheme and, if non-default, port: wss://host:8443/api/v1/tail
- Strip whitespace/quotes from the env value in CI before launching k6
Example fix
# before export K6_CLOUD_LOGS_TAIL_URL='cloudlogs.internal:443/api/v1/tail' # no scheme # after export K6_CLOUD_LOGS_TAIL_URL='wss://cloudlogs.internal:443/api/v1/tail'
Defensive patterns
Strategy: validation
Validate before calling
# reject malformed log-tail URLs before the run
python3 - <<'EOF'
from urllib.parse import urlparse
import os, sys
u = os.environ.get('K6_CLOUD_LOGS_TAIL_URL', 'wss://cloudlogs.k6.io/api/v1/tail')
p = urlparse(u)
assert p.scheme in ('ws', 'wss') and p.hostname, f'bad K6_CLOUD_LOGS_TAIL_URL: {u!r}'
EOF Prevention
- Always include the ws:// or wss:// scheme in K6_CLOUD_LOGS_TAIL_URL overrides
- Lint CI env files for values with spaces, quotes, or missing schemes
- Prefer unsetting the variable to inherit the tested default endpoint
When it happens
Trigger: K6_CLOUD_LOGS_TAIL_URL containing spaces or control characters, a missing scheme ('cloudlogs.k6.io/api/v1/tail'), or an invalid port ('wss://host:port'); a CI template or orchestrator injecting a mangled value.
Common situations: Custom log-tail endpoints for self-hosted setups specified without the ws:// or wss:// scheme; trailing whitespace or quotes around the env value; YAML/CI interpolation artifacts.
Related errors
- creating upload request: %w
- invalid stack URL: %w
- Run `k6 cloud login` to authenticate, or check the docs for
- access token not configured
- no project specified. Use --project-id, set K6_CLOUD_PROJECT
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/bbe660d52221d13f.
Report an issue: GitHub.