kubernetes/kops · error

must configure at least one ControlPlane InstanceGroup

Error message

must configure at least one ControlPlane InstanceGroup

What it means

DeepValidate requires at least one InstanceGroup with the ControlPlane role, because a Kubernetes cluster needs control-plane (master) nodes. It counts groups where g.IsControlPlane() is true and returns this error when the count is zero, even if node groups exist.

Source

Thrown at pkg/apis/kops/validation/legacy.go:291

		return errs.ToAggregate()
	}

	if len(groups) == 0 {
		return fmt.Errorf("must configure at least one InstanceGroup")
	}

	controlPlaneGroupCount := 0
	nodeGroupCount := 0
	for _, g := range groups {
		if g.IsControlPlane() {
			controlPlaneGroupCount++
		} else {
			nodeGroupCount++
		}
	}

	if controlPlaneGroupCount == 0 {
		return fmt.Errorf("must configure at least one ControlPlane InstanceGroup")
	}

	if nodeGroupCount == 0 {
		return fmt.Errorf("must configure at least one Node InstanceGroup")
	}

	for _, g := range groups {
		errs := CrossValidateInstanceGroup(g, c, cloud, strict)

		// Additional cloud-specific validation rules
		if c.GetCloudProvider() != kops.CloudProviderAWS && len(g.Spec.Volumes) > 0 {
			errs = append(errs, field.Forbidden(field.NewPath("spec", "volumes"), "instancegroup volumes are only available with aws at present"))
		}

		if len(errs) != 0 {
			return errs.ToAggregate()
		}
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Add an InstanceGroup with spec.role: ControlPlane (at least 1 replica, ideally 3 for HA)
  2. Fix the role field on an existing group from Node to ControlPlane via kops edit ig <name>
  3. Ensure group names don't implicitly confer roles — role must be explicitly ControlPlane
  4. Re-run kops update cluster --yes after correcting the group roles

Example fix

// before
spec:
  role: Node
  machineType: m5.large
// after
spec:
  role: ControlPlane
  machineType: m5.large
  minSize: 1
  maxSize: 1
Defensive patterns

Strategy: validation

Validate before calling

var cp, node int
for _, g := range groups {
    switch {
    case g.IsControlPlane():
        cp++
    case g.IsMaster(): // legacy role check fallback
        cp++
    default:
        node++
    }
}
if cp == 0 { return errors.New("add an InstanceGroup with spec.role: ControlPlane") }
if node == 0 { return errors.New("add an InstanceGroup with spec.role: Node") }

Type guard

func hasControlPlaneGroup(groups []*kops.InstanceGroup) bool {
    for _, g := range groups {
        if g.IsControlPlane() {
            return true
        }
    }
    return false
}

Try / catch

if err := validation.DeepValidate(cluster, groups, strict, vfsContext, cloud); err != nil {
    if strings.Contains(err.Error(), "ControlPlane InstanceGroup") {
        return fmt.Errorf("cluster %s lacks a ControlPlane instance group; set spec.role: ControlPlane on one group", cluster.Name)
    }
    return err
}

Prevention

When it happens

Trigger: Cluster definitions whose InstanceGroups all have role Node (or role unset/Bastion), passed to kops create cluster / kops update cluster / updateCluster, so controlPlaneGroupCount stays 0.

Common situations: Copy-pasting only node group manifests; setting spec.role: Node on every group by mistake; editing role names to a typo kops doesn't recognize (role defaults to Node); deleting the control-plane group during cluster edits.

Understand the failure class

Background: "X is required", "must be set", "cannot be empty": the missing-required-config error family, from Vertex AI project/location to WeChat keys — this error's family across 18 libraries.

Related errors


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