docker/cli · error · invalidParameterErr

failed to set custom headers from

Error message

failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'

What it means

Returned by withCustomHeadersFromEnv() when a CSV field from DOCKER_CUSTOM_HEADERS contains no '=' at all (cli_options.go:206-211). strings.Cut(kv,"=") returns hasValue=false when the separator is absent, so a token like 'X-Custom-Header' (no '=value') is rejected as an invalidParameter. Every header token must be a key=value pair.

Solutions

  1. Ensure every comma-separated token is in key=value form, even if the value is empty use 'X-Header='.
  2. Double-check for typos that dropped the '='.
  3. Validate with: echo "$DOCKER_CUSTOM_HEADERS" | tr ',' '\n' | grep -v '=' to spot offending tokens.

Example fix

// before
export DOCKER_CUSTOM_HEADERS='X-Custom,Authorization=Bearer x'   # first token has no '='
// after
export DOCKER_CUSTOM_HEADERS='X-Custom=value,Authorization=Bearer x'
Defensive patterns

Strategy: validation

Validate before calling

// Ensure every field contains '='.
func validateHeaderHasEquals(value string) error {
    r := csv.NewReader(strings.NewReader(value))
    fields, err := r.Read()
    if err != nil { return err }
    for _, kv := range fields {
        if _, _, ok := strings.Cut(kv, "="); !ok {
            return fmt.Errorf("header token missing '=': %q", kv)
        }
    }
    return nil
}

Prevention

When it happens

Trigger: Setting DOCKER_CUSTOM_HEADERS with a field that omits the '=' separator: 'X-Custom' instead of 'X-Custom=val', or a bare flag-like token. The per-field check fires as soon as any token lacks '='.

Common situations: Forgetting the value portion, using a header name as a toggle, or mixing key=value pairs with a bare header name.

Related errors


AI-assisted analysis of docker/cli@4f84911bfe (2026-08-07). Data as JSON: /api/errors/540b7c2b8cea6b30. Report an issue: GitHub.

Appendix: source

Thrown at cli/command/cli_options.go:207

	for _, kv := range fields {
		k, v, hasValue := strings.Cut(kv, "=")

		// Only strip whitespace in keys; preserve whitespace in values.
		k = strings.TrimSpace(k)

		if k == "" {
			return nil, invalidParameter(fmt.Errorf(
				`failed to set custom headers from %s environment variable: value contains a key=value pair with an empty key: '%s'`,
				envOverrideHTTPHeaders, kv,
			))
		}

		// We don't currently allow empty key=value pairs, and produce an error.
		// This is something we could allow in future (e.g. to read value
		// from an environment variable with the same name). In the meantime,
		// produce an error to prevent users from depending on this.
		if !hasValue {
			return nil, invalidParameter(fmt.Errorf(
				`failed to set custom headers from %s environment variable: missing "=" in key=value pair: '%s'`,
				envOverrideHTTPHeaders, kv,
			))
		}

		env[http.CanonicalHeaderKey(k)] = v
	}

	if len(env) == 0 {
		// We should probably not hit this case, as we don't skip values
		// (only return errors), but we don't want to discard existing
		// headers with an empty set.
		return nil, nil
	}

	// TODO(thaJeztah): add a client.WithExtraHTTPHeaders() function to allow these headers to be _added_ to existing ones, instead of _replacing_
	//  see https://github.com/docker/cli/pull/5098#issuecomment-2147403871  (when updating, also update the WARNING in the function and env-var GoDoc)
	return client.WithHTTPHeaders(env), nil

View on GitHub (pinned to 4f84911bfe)