kubernetes/kops · error

unhandled field: %q

Error message

unhandled field: %q

What it means

SetClusterFields parses each field argument as key=value; if a field has no '=' separator (SplitN yields 1 element) it returns 'unhandled field: %q'. It is a strict argument-format guard for the key=value field syntax used by create/edit cluster.

Source

Thrown at pkg/commands/set_cluster.go:32

limitations under the License.
*/

package commands

import (
	"fmt"
	"strings"

	api "k8s.io/kops/pkg/apis/kops"
	"k8s.io/kops/util/pkg/reflectutils"
)

// SetClusterFields sets field values in the cluster
func SetClusterFields(fields []string, cluster *api.Cluster) error {
	for _, field := range fields {
		kv := strings.SplitN(field, "=", 2)
		if len(kv) != 2 {
			return fmt.Errorf("unhandled field: %q", field)
		}

		key := kv[0]
		key = strings.TrimPrefix(key, "cluster.")

		key = api.InternalPathForClusterField(key)

		if err := reflectutils.SetString(cluster, key, kv[1]); err != nil {
			return err
		}
	}
	return nil
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure every field string contains '=' in the form key=value (e.g. cluster.spec.kubernetesVersion=1.30.0).
  2. Quote the whole argument in the shell so spaces/'=' survive: --set "spec.nodePortRange=30000-32767".
  3. Prefix cluster fields with 'cluster.' or 'spec.' as expected by api.InternalPathForClusterField.

Example fix

// before
fields := []string{"spec.kubernetesVersion"}
err := SetClusterFields(fields, cluster) // unhandled field: "spec.kubernetesVersion"
// after
fields := []string{"spec.kubernetesVersion=1.30.4"}
err := SetClusterFields(fields, cluster)
Defensive patterns

Strategy: validation

Validate before calling

func validClusterFields(fields []string) error {
	for _, f := range fields {
		if !strings.Contains(f, "=") {
			return fmt.Errorf("field %q must be key=value", f)
		}
	}
	return nil
}
// call before SetClusterFields

Type guard

func isKeyValue(s string) bool {
	parts := strings.SplitN(s, "=", 2)
	return len(parts) == 2 && parts[0] != ""
}

Try / catch

if err := SetClusterFields(fields, cluster); err != nil {
	if strings.HasPrefix(err.Error(), "unhandled field:") {
		var f string
		fmt.Sscanf(err.Error(), "unhandled field: %q", &f)
		return fmt.Errorf("field %q missing '=value'; use key=value", f)
	}
	return err
}

Prevention

When it happens

Trigger: Calling SetClusterFields with a slice entry like "spec.kubernetesVersion" (missing '=value'), e.g. `kops create cluster --set foo` without '='. TestSetClusterBadInput exercises exactly this.

Common situations: Typing `--set kubernetesVersion` instead of `--set kubernetesVersion=1.30.0`; quoting mistakes in shells that split values; mixing kubectl-style -l selectors with kops --set syntax.

Related errors


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