kubernetes/kops · error

kube-controller-manager nodes requires the ExperimentalRoles

Error message

kube-controller-manager nodes requires the ExperimentalRoles feature flag to be enabled

What it means

NewCluster validation guard: fires when an instance group has a kube-controller-manager-only role (nodes running only KCM) but the ExperimentalRoles feature flag is not enabled. Creating such instance groups is unsupported without the flag, so cluster creation is aborted.

Source

Thrown at upup/pkg/fi/cloudup/new_cluster.go:550

		} else if g.Spec.Role.HasBastion() {
			if g.Spec.MachineType == "" {
				g.Spec.MachineType, err = defaultMachineType(cloud, cluster, g)
				if err != nil {
					return nil, fmt.Errorf("error assigning default machine type for bastions: %v", err)
				}
			}
		} else {
			if g.IsAPIServerOnly() && !featureflag.APIServerNodes.Enabled() {
				return nil, fmt.Errorf("apiserver nodes requires the APIServerNodes feature flag to be enabled")
			}
			if !featureflag.ExperimentalRoles.Enabled() {
				switch {
				case g.Spec.Role.HasEtcd():
					return nil, fmt.Errorf("etcd nodes requires the ExperimentalRoles feature flag to be enabled")
				case g.Spec.Role.HasScheduler():
					return nil, fmt.Errorf("scheduler nodes requires the ExperimentalRoles feature flag to be enabled")
				case g.Spec.Role.HasKubeControllerManager():
					return nil, fmt.Errorf("kube-controller-manager nodes requires the ExperimentalRoles feature flag to be enabled")
				}
			}
			if g.Spec.MachineType == "" {
				g.Spec.MachineType, err = defaultMachineType(cloud, cluster, g)
				if err != nil {
					return nil, fmt.Errorf("error assigning default machine type for nodes: %v", err)
				}
			}

		}

		if ig.Spec.Tenancy != "" && ig.Spec.Tenancy != "default" {
			switch cluster.GetCloudProvider() {
			case api.CloudProviderAWS:
				if _, ok := awsDedicatedInstanceExceptions[g.Spec.MachineType]; ok {
					return nil, fmt.Errorf("invalid dedicated instance type: %s", g.Spec.MachineType)
				}
			default:

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Enable the flag: `export KOPS_FEATURE_FLAGS=ExperimentalRoles` and retry.
  2. Change the instance group role so kube-controller-manager runs on the control plane (default topology).
  3. Upgrade kops if the component split has since been stabilized.

Example fix

// before
kops create cluster --name=example.com   # kcm-only IG, flag unset
// after
export KOPS_FEATURE_FLAGS=ExperimentalRoles
kops create cluster --name=example.com
Defensive patterns

Strategy: validation

Validate before calling

if hasRole(igGroups, "kube-controller-manager") && !featureFlagEnabled("ExperimentalRoles") {
    return errors.New("ExperimentalRoles flag required for dedicated kcm IGs")
}

Try / catch

_, err := NewCluster(opt, cluster, zoneMap)
if err != nil {
    if strings.Contains(err.Error(), "kube-controller-manager nodes requires") {
        return fmt.Errorf("enable ExperimentalRoles or run kcm on control plane: %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: `kops create cluster` (or adding an IG) where a group's role has the kube-controller-manager component while KOPS_FEATURE_FLAGS lacks ExperimentalRoles.

Common situations: Highly customized cluster layouts; specs copied from experimental setups; environments where feature-flag env vars are stripped for security.

Related errors


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