grafana/k6 · error
metrics push URL is required
Error message
metrics push URL is required
What it means
The v2 cloud metrics output (output/cloud/expv2) pushes protobuf samples over HTTP through a metricsClient that must be built with an explicit push URL (newMetricsClientWithURL, output/cloud/expv2/metrics_client.go:53-56). This error means that by the time the output was constructed, no metrics ingestion URL existed: neither the provisioning backend's runtime_config.metrics.push_url nor the K6_CLOUD_METRICS_PUSH_URL environment variable supplied one (internal/cmd/outputs_cloud.go:204-225 wires these). Without a URL the output cannot send any samples, so construction fails fast rather than silently dropping metrics.
Source
Thrown at output/cloud/expv2/metrics_client.go:55
// A versioned client would be better but it would require a breaking
// change, and other services (e.g. k6-operator) depend on it, so we want
// to stabilize the API first.
func deriveMetricsURL(baseURL, testRunID string) (string, error) {
if !strings.HasSuffix(baseURL, "/v1") {
return "", errors.New("a /v1 suffix is expected in the Cloud service's BaseURL path")
}
if testRunID == "" {
return "", errors.New("TestRunID of the test is required")
}
return strings.TrimSuffix(baseURL, "/v1") + "/v2/metrics/" + testRunID, nil
}
// newMetricsClientWithURL builds a metricsClient with an explicit push URL.
// It is the single metricsClient constructor: callers that need the
// host-derived URL compute it via deriveMetricsURL first.
func newMetricsClientWithURL(c metricsHTTPClient, url string) (*metricsClient, error) {
if url == "" {
return nil, errors.New("metrics push URL is required")
}
return &metricsClient{
httpClient: c,
url: url,
}, nil
}
// Push the provided metrics for the given test run ID. The context cancels the
// underlying HTTP request so a stuck push cannot block k6 shutdown.
func (mc *metricsClient) push(ctx context.Context, samples *pbcloud.MetricSet) error {
b, err := newRequestBody(samples)
if err != nil {
return err
}
req, err := http.NewRequestWithContext(
ctx, http.MethodPost, mc.url, io.NopCloser(bytes.NewReader(b)))
if err != nil {View on GitHub (pinned to 93accf6570)
Solutions
- If an orchestration service provisions the run itself, export both K6_CLOUD_METRICS_PUSH_URL and K6_CLOUD_TEST_RUN_TOKEN (k6 errors early if only one is set - internal/cmd/outputs_cloud.go:222-225)
- Verify the start_local_execution response actually contains runtime_config.metrics.push_url; if your backend returns it empty, fix the backend or supply the env override
- For the legacy '-o cloud' path, ensure the cloud BaseURL ends with /v1 and a reference ID exists so deriveMetricsURL can build the URL (output/cloud/expv2/metrics_client.go:40-48)
- Update k6 - older builds had different push-URL plumbing between provisioning and the expv2 output
Example fix
# before (orchestrator-managed run, no credentials exported) k6 cloud run --local-execution script.js # after export K6_CLOUD_METRICS_PUSH_URL='https://ingest.grafana.net/v2/metrics/1234567' export K6_CLOUD_TEST_RUN_TOKEN='eyJ...' k6 cloud run --local-execution script.js
Defensive patterns
Strategy: validation
Validate before calling
# before launching an orchestrator-managed local-execution run if [ -z "$K6_CLOUD_METRICS_PUSH_URL" ] || [ -z "$K6_CLOUD_TEST_RUN_TOKEN" ]; then echo 'missing push credentials: set K6_CLOUD_METRICS_PUSH_URL and K6_CLOUD_TEST_RUN_TOKEN' >&2 exit 1 fi k6 cloud run --local-execution script.js
Prevention
- Always export K6_CLOUD_METRICS_PUSH_URL and K6_CLOUD_TEST_RUN_TOKEN as a pair; k6 fails fast when only one is present
- Smoke-test custom provisioning backends by asserting runtime_config.metrics.push_url is non-empty in the response
- Pin and update k6 deliberately so provisioning and expv2 output stay version-aligned
When it happens
Trigger: Running 'k6 cloud run --local-execution' where the orchestrator did not export K6_CLOUD_METRICS_PUSH_URL (and K6_CLOUD_TEST_RUN_TOKEN); a provisioning backend that returns a runtime_config with an empty metrics.push_url; or an embedder calling newMetricsClientWithURL directly with an empty string (metrics_client_test.go:90 exercises exactly this).
Common situations: CI pipelines or the k6-operator provisioning the run themselves but forgetting the scoped push credentials; an old or non-standard K6_CLOUD_HOST whose backend does not return the v2 runtime_config; typo'd env var name so the value never reaches k6.
Related errors
- no project specified. Use --project-id, set K6_CLOUD_PROJECT
- no secret sources are configured
- Run `k6 cloud login` to authenticate, or check the docs for
- access token not configured
- 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/d9b87ee1a7675fb4.
Report an issue: GitHub.