grafana/k6 · error

generating idempotency key

Error message

generating idempotency key: %w

What it means

Returned by Client.StartLocalExecution (internal/cloudapi/provisioning/api.go:195) when crypto/rand.Read fails while generating the 8 random bytes for the K6-Idempotency-Key header. The Go standard library's rand.Read essentially never fails on modern operating systems; when it does, the system's entropy source (/dev/urandom or getrandom(2)) is unavailable or broken in the execution environment. No network call has happened yet when this fires.

Solutions

  1. Verify /dev/urandom exists and is readable inside the environment: 'ls -l /dev/urandom && head -c 8 /dev/urandom | xxd'.
  2. If running a minimal container, ensure device nodes are set up (proper --device /tmpfs or init system) or use a fuller base image.
  3. Relax the sandbox/seccomp profile to allow the getrandom syscall.
  4. In tests, stop overriding crypto/rand.Reader with an erroring stub, or make the stub succeed.
Defensive patterns

Strategy: retry

Validate before calling

// Environment pre-flight: crypto/rand must be readable.
func entropyAvailable() bool {
	b := make([]byte, 8)
	_, err := rand.Read(b)
	return err == nil
}

Try / catch

if _, err := c.StartLocalExecution(ctx, id, req); err != nil && strings.Contains(err.Error(), "generating idempotency key") {
	// entropy source broken — fixing the environment is the only cure; a retry cannot succeed
	return fmt.Errorf("system entropy source unavailable; check /dev/urandom in this container: %w", err)
}

Prevention

When it happens

Trigger: crypto/rand.Read returning an error: containers/VMs with /dev/urandom missing or not yet initialized (very early boot), restricted sandbox/seccomp profiles blocking getrandom, or test code having replaced the crypto/rand Reader with one that errors.

Common situations: Minimal container images (distroless/scratch variants with broken device nodes); heavily sandboxed CI executors; Go tests overriding rand.Reader; ancient kernels without getrandom support.

Related errors


AI-assisted analysis of grafana/k6@01ffac6f24 (2026-08-18). Data as JSON: /api/errors/8390cccdd839d82f. Report an issue: GitHub.

Appendix: source

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

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

// StartLocalExecution starts a local-execution test run via the
// provisioning API. It generates a K6-Idempotency-Key header for
// safe retries. The caller provides options as pre-marshalled JSON.
func (c *Client) StartLocalExecution(
	ctx context.Context, loadTestID int64, req StartLocalExecutionRequest,
) (*StartLocalExecutionResponse, error) {
	// Generate idempotency key: 8 random bytes hex-encoded (16 chars).
	var key [8]byte
	if _, err := rand.Read(key[:]); err != nil {
		return nil, fmt.Errorf("generating idempotency key: %w", err)
	}

	// SDK adapter: unmarshal json.RawMessage → map[string]any.
	var opts map[string]any
	if err := json.Unmarshal(req.Options, &opts); err != nil {
		return nil, fmt.Errorf("unmarshalling options for SDK: %w", err)
	}

	maxVUs, err := toInt32(req.MaxVUs)
	if err != nil {
		return nil, fmt.Errorf("max_vus: %w", err)
	}
	totalDuration, err := toInt32(req.TotalDuration)
	if err != nil {
		return nil, fmt.Errorf("total_duration: %w", err)
	}

	sdkReq := k6cloud.NewStartLocalExecutionTestRequest(opts, maxVUs, totalDuration)

View on GitHub (pinned to 01ffac6f24)