grafana/k6 · error

token is required to create provisioning API client

Error message

token is required to create provisioning API client

What it means

Returned by provisioning.NewClient (internal/cloudapi/provisioning/client.go:47) when the token argument is an empty string — the client refuses to construct without cloud API credentials because every subsequent call would fail with opaque 401s. The token is the k6 Cloud / Grafana Cloud k6 API token normally supplied via K6_CLOUD_TOKEN or k6 cloud login. Failing here is intentional and the earliest possible point to catch a missing credential.

Solutions

  1. Set the token: export K6_CLOUD_TOKEN=<token> or run 'k6 cloud login' (or 'k6 cloud login --token <token>' non-interactively).
  2. In CI, verify the secret variable name and that it is exposed to the step (print ${#K6_CLOUD_TOKEN} to check length without leaking it).
  3. If constructing the client in Go, resolve and validate the token before calling NewClient (see defense code).
  4. Create a token in Grafana Cloud (k6 plugin → API tokens) with sufficient scope if none exists.

Example fix

// before
c, err := provisioning.NewClient(logger, os.Getenv("K6_CLOUD_TOKEN"), host, version, stackID, timeout)

// after — validate before constructing, with an actionable message
token := os.Getenv("K6_CLOUD_TOKEN")
if token == "" {
	return nil, errors.New("K6_CLOUD_TOKEN is not set; run 'k6 cloud login' or export it in CI")
}
c, err := provisioning.NewClient(logger, token, host, version, stackID, timeout)
Defensive patterns

Strategy: validation

Validate before calling

token := strings.TrimSpace(os.Getenv("K6_CLOUD_TOKEN"))
if token == "" {
	return nil, errors.New("K6_CLOUD_TOKEN not set — run 'k6 cloud login' or define it in CI secrets")
}
c, err := provisioning.NewClient(logger, token, host, version, stackID, timeout)

Try / catch

if _, err := provisioning.NewClient(logger, token, host, version, stackID, timeout); err != nil {
	if strings.Contains(err.Error(), "token is required") {
		// credential bootstrap problem: guide user to login; do not retry
		os.Stderr.WriteString("Missing k6 Cloud token. Run: k6 cloud login\n")
	}
	return err
}

Prevention

When it happens

Trigger: Calling NewClient with token == "": environment variable K6_CLOUD_TOKEN unset or empty in the shell/CI, 'k6 cloud login' never run or its stored token cleared, or an explicit empty-string token passed programmatically.

Common situations: CI pipelines where the secret name is misspelled (K6_CLOUD_TOKEN vs K6_CLOUD_API_TOKEN) or the secret scoped to another environment; fresh machines/clones without cloud login; scripts reading the token from a config file that has an empty field.

Related errors


AI-assisted analysis of grafana/k6@8d06114777 (2026-08-18). Data as JSON: /api/errors/4be6d79be7e700aa. Report an issue: GitHub.

Appendix: source

Thrown at internal/cloudapi/provisioning/client.go:47

	stackID   int64
	host      string
	version   string

	logger logrus.FieldLogger
}

// NewClient returns a new provisioning Client. It internally constructs
// both a k6cloud.APIClient (for provisioning endpoints) and a v6.Client
// (for v6 operations like FetchTest). The stackID identifies the
// Grafana Cloud stack and is required for the stack-scoped requests.
func NewClient(
	logger logrus.FieldLogger,
	token, host, version string,
	stackID int64,
	timeout time.Duration,
) (*Client, error) {
	if token == "" {
		return nil, fmt.Errorf("token is required to create provisioning API client")
	}

	cfg := clientcfg.New(host, version, "k6 Cloud API (provisioning).", timeout)

	v6c, err := v6.NewClient(logger, token, host, version, timeout)
	if err != nil {
		return nil, fmt.Errorf("creating v6 client: %w", err)
	}

	c := &Client{
		apiClient: k6cloud.NewAPIClient(cfg),
		v6Client:  v6c,
		token:     token,
		stackID:   stackID,
		host:      host,
		version:   version,
		logger:    logger,
	}

View on GitHub (pinned to 8d06114777)