grafana/k6 · error

invalid environment variable name '%s'

Error message

invalid environment variable name '%s'

What it means

Values passed via --env / -e become script environment variables (__ENV). k6 accepts only names matching ^[a-zA-Z_][a-zA-Z0-9_]*$ (ASCII letters, digits, underscore, not starting with a digit); anything else — hyphens, dots, leading digits, unicode — is rejected before the run starts with "invalid environment variable name '<name>'."

Source

Thrown at internal/cmd/runtime_options.go:69

	environment map[string]string,
) (lib.RuntimeOptions, error) {
	// TODO: refactor with composable helpers as a part of #883, to reduce copy-paste
	// TODO: get these options out of the JSON config file as well?
	opts, err := populateRuntimeOptionsFromEnv(runtimeOptionsFromFlags(flags), environment)
	if err != nil {
		return opts, err
	}

	// Set/overwrite environment variables with custom user-supplied values
	envVars, err := flags.GetStringArray("env")
	if err != nil {
		return opts, err
	}
	for _, kv := range envVars {
		k, v := state.ParseEnvKeyValue(kv)
		// Allow only alphanumeric ASCII variable names for now
		if !userEnvVarName.MatchString(k) {
			return opts, fmt.Errorf("invalid environment variable name '%s'", k)
		}
		opts.Env[k] = v
	}

	return opts, nil
}

func runtimeOptionsFromFlags(flags *pflag.FlagSet) lib.RuntimeOptions {
	opts := lib.RuntimeOptions{
		TestType:                  getNullString(flags, "type"),
		IncludeSystemEnvVars:      getNullBool(flags, "include-system-env-vars"),
		CompatibilityMode:         getNullString(flags, "compatibility-mode"),
		NoThresholds:              getNullBool(flags, "no-thresholds"),
		SummaryMode:               getNullString(flags, "summary-mode"),
		SummaryExport:             getNullString(flags, "summary-export"),
		NewMachineReadableSummary: getNullBool(flags, "new-machine-readable-summary"),
		TracesOutput:              getNullString(flags, "traces-output"),
		Env:                       make(map[string]string),

View on GitHub (pinned to 93accf6570)

Solutions

  1. Rename the variable using only letters, digits, and underscore: my-var becomes MY_VAR
  2. Quote the whole assignment so the shell passes it intact: k6 run -e 'MY_VAR=value with spaces' script.js
  3. If you need arbitrary keys, ship them via a JSON file loaded with open() inside the script instead of --env

Example fix

# before
k6 run -e my-var=1 script.js
# after
k6 run -e MY_VAR=1 script.js
Defensive patterns

Strategy: validation

Validate before calling

# Validate -e names exactly like k6 does (^[a-zA-Z_][a-zA-Z0-9_]*$)
for kv in "$@"; do
  k=${kv%%=*}
  echo "$k" | grep -Eq '^[a-zA-Z_][a-zA-Z0-9_]*$' || { echo "invalid env name: $k" >&2; exit 2; }
done
k6 run -e "$@" script.js

Prevention

When it happens

Trigger: k6 run -e 'my-var=1' script.js (hyphen), k6 run -e '2fa=on' script.js (leading digit), k6 run -e 'app.db=postgres' script.js (dot). ParseEnvKeyValue splits on the first '=' and the extracted key fails userEnvVarName.MatchString.

Common situations: Pasting shell-style kebab-case names into -e; splitting connection strings on '=' so the key contains symbols; migrating from tools that accept arbitrary variable names.

Related errors


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