grafana/k6 · error
start local execution
Error message
start local execution: %w
What it means
The StartLocalExecution call inside ProvisionLocalExecution failed — the request to begin a cloud-managed local-execution run (carrying Options, MaxVUs, TotalDuration, ArchiveSize) was rejected or did not complete. The wrapped error distinguishes HTTP rejection (ResponseError with status/body) from transport failure (network error).
Solutions
- Check the wrapped error's HTTP status and body — fix the reported field (options vs MaxVUs vs duration)
- Stop any still-running previous run of the same test in the Grafana Cloud UI or via `k6 cloud` commands, then retry
- Verify quota/plan limits for concurrent runs, max VUs, and duration in your Grafana Cloud project
- Re-authenticate with `k6 cloud login` if the status is 401/403
Example fix
// before
maxVUs := int64(1000) // hand-typed, may contradict script options
sleResp, err := client.StartLocalExecution(ctx, loadTestID, provisioning.StartLocalExecutionRequest{MaxVUs: maxVUs, ...})
// after
maxVUs := int64(et.GetMaxPossibleVUs()) // derived from the same execution plan
sleResp, err := client.StartLocalExecution(ctx, loadTestID, provisioning.StartLocalExecutionRequest{MaxVUs: maxVUs, ...}) Defensive patterns
Strategy: try-catch
Validate before calling
// keep sizing consistent with the execution plan before calling
et, err := lib.NewExecutionTuple(seg, seq)
if err != nil { return err }
plan := cfg.Scenarios.GetFullExecutionRequirements(et)
maxVUs := int64(plan.GetMaxPossibleVUs())
total := int64(plan.GetDuration() / time.Second) Try / catch
sleResp, err := c.StartLocalExecution(ctx, loadTestID, sleReq)
if err != nil {
var respErr *cloudapiv6.ResponseError
if errors.As(err, &respErr) {
switch respErr.Response.StatusCode {
case 409: return nil, fmt.Errorf("previous run still active: %w", err)
case 402, 429: return nil, fmt.Errorf("quota exceeded: %w", err)
}
}
return nil, fmt.Errorf("start local execution: %w", err)
} Prevention
- Derive MaxVUs/TotalDuration from the same execution plan you send as Options
- Stop previous runs of the same test before starting a new one (scripted `k6 cloud stop`)
- Surface 402/429 distinctly so operators know it is quota, not a bug
When it happens
Trigger: 400 validation when MaxVUs or TotalDuration contradict the marshalled options, quota/plan limits exceeded (402/429), another run of the same test still active (409), invalid token (401), or network failure reaching the provisioning endpoint.
Common situations: Sizing parameters computed from a script whose scenarios changed between builds, free-tier limits on VUs or duration, a leftover running test from a crashed previous session, or a stale login configuration.
Understand the failure class
Background: "API request failed": what wrapped HTTP errors from external APIs mean and how to find the real cause — this error's family across 29 libraries.
Related errors
- create or find load test
- invalid stack URL
- max_vus
- notify test run completed
- stack URL is required to validate token
AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18).
Data as JSON: /api/errors/7b51a84ebca74921.
Report an issue: GitHub.
Appendix: source
Thrown at internal/cloudapi/provisioning/provision.go:87
if params.Archive != nil {
var buf bytes.Buffer
if err := params.Archive.Write(&buf); err != nil {
return nil, fmt.Errorf("serialising archive: %w", err)
}
archiveSize = int64(buf.Len())
archiveBytes = buf.Bytes()
}
sleReq := StartLocalExecutionRequest{
Options: params.Options,
MaxVUs: params.MaxVUs,
TotalDuration: params.TotalDuration,
ArchiveSize: archiveSize,
}
sleResp, err := c.StartLocalExecution(ctx, loadTestID, sleReq)
if err != nil {
return nil, fmt.Errorf("start local execution: %w", err)
}
switch {
case params.Archive != nil && sleResp.ArchiveUploadURL != nil:
if err := c.UploadArchive(ctx, *sleResp.ArchiveUploadURL, archiveBytes); err != nil {
return nil, fmt.Errorf("upload archive: %w", err)
}
case params.Archive != nil && sleResp.ArchiveUploadURL == nil:
// We had an archive to upload but the API returned no upload URL;
// proceed without uploading rather than failing the run.
c.logger.Warn("archive present but provisioning API returned no upload URL; skipping archive upload")
}
if err := c.WaitForTestRunReady(ctx, sleResp.TestRunID, params.PollInterval); err != nil {
return nil, fmt.Errorf("wait for test run ready: %w", err)
}
return &ProvisionResult{View on GitHub (pinned to 01ffac6f24)