kubernetes/kops · error

Error too many '=' (%d) in %s

Error message

Error too many '=' (%d) in %s

What it means

parseLabels parses the --node-labels flag value, a comma-separated list of key=value pairs. If any individual pair contains more than one '=' character (i.e. splitting on '=' yields more than 2 parts), it rejects the input because label keys and values cannot themselves contain '='. Note the message prints the whole []string pair with %s, which produces malformed output like [key value=extra].

Source

Thrown at channels/pkg/cmd/apply_channel.go:91

			return runApplyChannelIteration(context.TODO(), f, out, &options, args)
		},
	}

	cmd.Flags().BoolVar(&options.Yes, "yes", false, "Apply update")
	cmd.Flags().DurationVar(&options.Interval, "interval", 0, "If non-zero, re-apply the channel on this interval until interrupted (e.g. 60s)")
	cmd.Flags().StringVar(&options.NodeName, "node-name", "", "If set, patch the named node with the mandatory control-plane labels each iteration; typically supplied via the downward API.")
	cmd.Flags().StringVar(&rawLabels, "node-labels", "", "If set, patch the named node with each of the label,value pairs each iteration; typically supplied via the downward API.")

	return cmd
}

func parseLabels(rawLabels string) (map[string]string, error) {
	labels := make(map[string]string)
	pairs := strings.Split(rawLabels, ",")
	for _, rawpair := range pairs {
		pair := strings.Split(rawpair, "=")
		if len(pair) > 2 {
			return nil, fmt.Errorf("Error too many '=' (%d) in %s", len(pair), pair)
		} else if len(pair) == 2 {
			labels[pair[0]] = pair[1]
		} else {
			labels[rawpair] = ""
		}
	}
	return labels, nil
}

// runApplyChannelIteration patches node labels (when --node-name is set) then
// applies the channel. Labels go first so addons targeting the control-plane
// label can schedule on the local node as soon as their manifests land.
func runApplyChannelIteration(ctx context.Context, f *ChannelsFactory, out io.Writer, options *ApplyChannelOptions, args []string) error {
	var merr error
	if options.NodeName != "" {
		labelerClient, err := f.KubernetesClient()
		if err != nil {
			merr = multierr.Append(merr, fmt.Errorf("building kubernetes client for node labeler: %w", err))

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Remove the extra '=' from the offending key=value pair so each comma-separated item has at most one '='
  2. If the label value legitimately needs '=', use a Kubernetes-valid encoding (label values only allow alphanumerics, '-', '_', '.')
  3. Check shell quoting/interpolation so an unintended '=' is not injected into --node-labels
  4. Wrap in single quotes so the shell does not split or mangle the value

Example fix

// before
--node-labels "node-role.kubernetes.io/control-plane=,topology.kubernetes.io/zone=us=east-1"
// after
--node-labels "node-role.kubernetes.io/control-plane=,topology.kubernetes.io/zone=us-east-1"
Defensive patterns

Strategy: validation

Validate before calling

func validateLabels(raw string) error {
	for _, item := range strings.Split(raw, ",") {
		if strings.Count(item, "=") > 1 {
			return fmt.Errorf("label pair %q has more than one '='", item)
		}
	}
	return nil
}
// call before running: validateLabels(nodeLabelsFlag)

Prevention

When it happens

Trigger: Running `kops channels --node-name <node> --node-labels "k=v=w"` or any flag value where a single comma-separated item contains two or more '=' characters (e.g. a value that was not quoted/escaped, or a stray '=' from shell interpolation).

Common situations: Copy-pasting labels with embedded '=' from manifests; shell scripts interpolating variables containing '='; attempting to set a label value with '=' inside (invalid in Kubernetes anyway); typos like 'a=b=c' instead of 'a=b'.

Understand the failure class

Background: "unknown output mode", "invalid value for flag", "expects true/false": fixing invalid flag value errors in CLI tools — this error's family across 24 libraries.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/744efe0aeac254db. Report an issue: GitHub.