kubernetes/kops · error

unhandled instanceGroup role %q

Error message

unhandled instanceGroup role %q

What it means

BuildNodeLabels maps the InstanceGroup role to node labels. Roles are matched against control-plane, node, and bastion; any other/unset role hits the default branch and throws. This is a role-dispatch exhaustiveness guard.

Source

Thrown at pkg/nodelabels/builder.go:60

)

// BuildNodeLabels returns the node labels for the specified instance group
// This moved from the kubelet to a central controller in kubernetes 1.16
func BuildNodeLabels(cluster *api.Cluster, instanceGroup *api.InstanceGroup) (map[string]string, error) {
	isControlPlane := false
	isAPIServer := false
	isNode := false
	switch {
	case instanceGroup.Spec.Role.HasControlPlane():
		isControlPlane = true
	case instanceGroup.Spec.Role.HasAPIServer():
		isAPIServer = true
	case instanceGroup.Spec.Role.HasNode():
		isNode = true
	case instanceGroup.Spec.Role.HasBastion():
		// no labels to add
	default:
		return nil, fmt.Errorf("unhandled instanceGroup role %q", instanceGroup.Spec.Role)
	}

	// Merge KubeletConfig for NodeLabels
	c := &api.KubeletConfigSpec{}
	if isControlPlane {
		reflectutils.JSONMergeStruct(c, cluster.Spec.ControlPlaneKubelet)
	} else {
		reflectutils.JSONMergeStruct(c, cluster.Spec.Kubelet)
	}

	if instanceGroup.Spec.Kubelet != nil {
		reflectutils.JSONMergeStruct(c, instanceGroup.Spec.Kubelet)
	}

	nodeLabels := c.NodeLabels

	if isAPIServer || isControlPlane {
		if nodeLabels == nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Set instanceGroup.spec.role to a valid value: ControlPlane, Master (legacy), Node, or Bastion
  2. Re-run kops get ig / validate to ensure the spec parses into a known role
  3. Upgrade/downgrade kOps so the role value matches a supported version of the schema

Example fix

// before
spec:
  role: ""
// after
spec:
  role: Node
Defensive patterns

Strategy: validation

Validate before calling

func validRole(r kops.InstanceGroupRole) bool {
    return r == kops.InstanceGroupRoleControlPlane || r == kops.InstanceGroupRoleMaster ||
        r == kops.InstanceGroupRoleNode || r == kops.InstanceGroupRoleBastion
}
if !validRole(ig.Spec.Role) {
    return fmt.Errorf("ig %s has invalid role %q", ig.Name, ig.Spec.Role)
}

Type guard

func hasKnownRole(ig *api.InstanceGroup) bool {
    return ig != nil && validRole(ig.Spec.Role)
}

Prevention

When it happens

Trigger: An InstanceGroup whose Spec.Role is empty or not one of Master/ControlPlane/Node/Bastion is passed to BuildNodeLabels (via CloudTagsForInstanceGroup, PopulateInstanceGroupSpec, etc.).

Common situations: Hand-edited cluster YAML missing the role field on an instance group; JSON/YAML typo in role name; older/newer cluster spec version with a role not supported by this kOps build.

Related errors


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