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

  1. Unwrap and read the exact status/body: auth vs not-found vs validation vs quota each have different fixes
  2. Verify the load test exists and the token can execute tests in that project
  3. Check org quotas and plan limits in Grafana Cloud
  4. Upgrade (or pin) k6 to a version aligned with the current cloud API if 400/422 schema errors appear
  5. 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

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


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