grafana/k6 · error

test run completed before k6 could start

Error message

test run completed before k6 could start

What it means

Returned by Client.WaitForTestRunReady (internal/cloudapi/provisioning/api.go:167) when polling GET /cloud/v6/test_runs/{id} during --local-execution provisioning. The loop waits for status 'initializing' as the signal that k6 may begin local execution; if the backend reports 'completed' first, this k6 process can never attach to the run and the error is returned immediately.

Source

Thrown at internal/cloudapi/provisioning/api.go:167

		switch v6.Status(status) {
		case v6.StatusInitializing:
			return nil

		case v6.StatusAborted:
			var abortMsg string
			for _, e := range progress.StatusHistory {
				if e.Status == v6.StatusAborted && e.Message != "" {
					abortMsg = e.Message
					break
				}
			}
			if abortMsg != "" {
				return fmt.Errorf("test run aborted before starting: %s", abortMsg)
			}
			return fmt.Errorf("test run aborted before starting")

		case v6.StatusCompleted:
			return fmt.Errorf("test run completed before k6 could start")

		default:
			// created, queued, or any unrecognised state — keep polling.
			if status != lastStatus {
				c.logger.WithField("status", progress.FormatStatus()).Debug("test status")
				lastStatus = status
			}
		}

		select {
		case <-ctx.Done():
			return ctx.Err()
		case <-time.After(pollInterval):
			// continue polling
		}
	}
}

View on GitHub (pinned to 93accf6570)

Solutions

  1. Check the Grafana Cloud UI for the run's status history to see who/what completed it
  2. Ensure only one k6 process provisions this load test at a time
  3. Start a fresh test run instead of reusing the previous testRunID
  4. If it recurs consistently, capture the status transitions via debug logging (k6 sets 'test status' Debug lines) and report a backend issue

Example fix

// before
if err := client.WaitForTestRunReady(ctx, testRunID, 0); err != nil {
	return err
}

// after
if err := client.WaitForTestRunReady(ctx, testRunID, 0); err != nil {
	if strings.Contains(err.Error(), "completed before k6 could start") {
		// run already finished server-side; provision a new run
		return provisionFreshRun(ctx)
	}
	return err
}
Defensive patterns

Strategy: try-catch

Type guard

func isCompletedBeforeStart(err error) bool {
	return err != nil && strings.Contains(err.Error(), "test run completed before k6 could start")
}

Try / catch

err := client.WaitForTestRunReady(ctx, resp.TestRunID, pollInterval)
if err != nil {
	if isCompletedBeforeStart(err) {
		// terminal: provision a fresh run rather than retrying this one
	}
	return err
}

Prevention

When it happens

Trigger: ProvisionLocalExecution -> WaitForTestRunReady observes v6.StatusCompleted before v6.StatusInitializing. Happens when another executor already finished the run, when the same test run ID is re-used by a parallel process, or when a backend state race skips 'initializing' entirely.

Common situations: Duplicate/parallel k6 processes provisioning the same load test with the same token; retrying an old provisioning request that references a stale test run; backend-side automation that completed or force-completed the run between creation and the first poll.

Related errors


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