grafana/k6 · critical
start local execution: %w
Error message
start local execution: %w
What it means
Client.ProvisionLocalExecution (internal/cloudapi/provisioning/provision.go:87) wraps the failure of Client.StartLocalExecution — the POST start_local_execution call. This is an umbrella error: it can be any of the request-building failures (idempotency key, options JSON, int32 conversions) or, most commonly, a non-2xx from CheckResponse (401/403 auth, 404 unknown load test, 409/422 rejected request, 5xx) or a transport error.
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 93accf6570)
Solutions
- Unwrap and read the exact status/body: auth vs not-found vs validation vs quota each have different fixes
- Verify the load test exists and the token can execute tests in that project
- Check org quotas and plan limits in Grafana Cloud
- Upgrade (or pin) k6 to a version aligned with the current cloud API if 400/422 schema errors appear
- Re-run once to rule out transient 5xx (the K6-Idempotency-Key makes retries safe)
Defensive patterns
Strategy: try-catch
Validate before calling
if loadTestID <= 0 {
return errors.New("invalid load test ID; cannot start local execution")
}
if !json.Valid(params.Options) {
return errors.New("options JSON invalid; refusing to start local execution")
} Type guard
func isProvisioningHTTPError(err error) (int, bool) {
var re *provisioning.ResponseError
if errors.As(err, &re) {
return re.StatusCode, true
}
return 0, false
} Try / catch
res, err := client.ProvisionLocalExecution(ctx, params)
if err != nil {
if code, ok := isProvisioningHTTPError(err); ok {
switch {
case code == 401 || code == 403:
// token scope problem
case code == 404:
// load test / endpoint mismatch
case code >= 500:
// safe to retry: request carried an idempotency key
}
}
return err
} Prevention
- Pre-validate options JSON and numeric fields before provisioning
- Keep k6 updated in lockstep with cloud API releases
- Rely on the K6-Idempotency-Key and retry 5xxs instead of abandoning runs
- Inspect status+body before changing configuration — the umbrella message alone is ambiguous
When it happens
Trigger: loadTestID returned by CreateOrFindLoadTest is not startable; backend rejects the submitted options or archive size; token lacks execution permission; org quota/plan limits hit; cloud API version incompatible with this k6 build.
Common situations: Free-tier or quota exhaustion; schema drift after a cloud API release versus an older k6; tokens with read-only scopes; archive/options mismatches after script changes.
Related errors
- archive upload failed: %d %s
- archive upload failed: %d %s: %s
- fetching test status: %w
- test run aborted before starting: %s
- test run completed before k6 could start
AI-assisted analysis of grafana/k6@93accf6570 (2026-08-15).
Data as JSON: /api/errors/7b51a84ebca74921.
Report an issue: GitHub.