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
- Enable the flag: `export KOPS_FEATURE_FLAGS=ExperimentalRoles` and retry.
- Change the instance group role so kube-controller-manager runs on the control plane (default topology).
- 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
- Validate IG role strings before submitting specs
- Centralize feature-flag configuration
- Only split control-plane components when the flag is intentionally enabled
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
- apiserver nodes requires the APIServerNodes feature flag to
- etcd nodes requires the ExperimentalRoles feature flag to be
- scheduler nodes requires the ExperimentalRoles feature flag
- error parsing Kubernetes version %q: %v
- cannot find subnet %q (declared in instance group %q, not fo
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/0c7d5e99caa2adee.
Report an issue: GitHub.