grafana/k6 · error

secret source for name

Error message

secret source for name %q already registered before configuration %q

What it means

Every secret source gets a name: taken from the name=... key inside its comma-separated config, otherwise defaulting to the source type. Two --secret-source entries resolving to the same name make the second registration fail. Note the message prints the source TYPE (the first %q is the type) along with the full second configuration line.

Solutions

  1. Give each source a unique name: --secret-source=file,name=a=a.txt --secret-source=file,name=b=b.txt
  2. If you only need one source of that type, delete the duplicate entry
  3. Check every name= key across all entries — names must be unique

Example fix

# before
k6 run --secret-source=file=a.txt --secret-source=file=b.txt script.js

# after
k6 run --secret-source=file,name=a=a.txt --secret-source=file,name=b=b.txt script.js
Defensive patterns

Strategy: validation

Validate before calling

# collect source names (name= key or the type) and reject duplicates before running
check_names() {
  declare -A seen
  for entry in "$@"; do
    type="${entry%%=*}"; config="${entry#*=}"
    name="$type"
    for kv in ${config//,/ }; do [ "${kv%%=*}" = name ] && name="${kv#*=}"; done
    [ -n "${seen[$name]:-}" ] && { echo "duplicate secret source name: $name" >&2; return 1; }
    seen[$name]=1
  done
}
check_names "file=a.txt" "file,name=b=b.txt" || exit 1

Prevention

When it happens

Trigger: --secret-source=file=a.txt --secret-source=file=b.txt (both default to name 'file'); or two entries with the same explicit name, e.g. --secret-source=file,name=x=... --secret-source=mock,name=x=...

Common situations: Wanting two files as secret sources without naming them; copy-pasting a --secret-source line and editing only the path; migrating a shared config to multiple sources.

Related errors


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

Appendix: source

Thrown at internal/cmd/root.go:531

		if !ok {
			return nil, fmt.Errorf("no secret source for type %q for configuration %q", t, line)
		}
		c := found.Module.(secretsource.Constructor) //nolint:forcetypeassert
		params := baseParams
		name, isDefault, config := extractNameAndDefault(config)
		if name == "" {
			// Default the name to the source type to avoid an empty-string key.
			name = t
		}
		params.ConfigArgument = config

		secretSource, err := c(params)
		if err != nil {
			return nil, err
		}
		_, alreadRegistered := result[name]
		if alreadRegistered {
			return nil, fmt.Errorf("secret source for name %q already registered before configuration %q", t, line)
		}
		result[name] = secretSource
		if isDefault {
			if _, ok := result["default"]; ok {
				return nil, fmt.Errorf("can't have two secret sources that are default ones, second one was %q", config)
			}
			result["default"] = secretSource
		}
	}

	if len(result) == 1 {
		for _, l := range result {
			result["default"] = l
		}
	}

	// Capture the cloud source instance if it was registered (via local-execution auto-injection
	// or the env-var path below), so createCloudTest can call SetConfig on it later.

View on GitHub (pinned to 8d06114777)