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
- Set instanceGroup.spec.role to a valid value: ControlPlane, Master (legacy), Node, or Bastion
- Re-run kops get ig / validate to ensure the spec parses into a known role
- 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
- Always set spec.role explicitly in InstanceGroup manifests
- Run kops validate/replace on manifests before applying
- Keep role enums in sync with the kOps version in use
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
- must specify %q label with cluster name to replace instanceG
- cannot determine role for instance group: %v
- did not find owner for node %q
- invalid InstanceGroup name: %v
- error building InstanceGroup from CAPI Machine: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2909f3866c48e14f.
Report an issue: GitHub.