kubernetes/kops · error
error building InstanceGroup from CAPI Machine: %w
Error message
error building InstanceGroup from CAPI Machine: %w
What it means
For CAPI-managed nodes with no direct InstanceGroup name, getNodeConfig synthesizes an InstanceGroup from the verified Cluster API Machine via s.buildInstanceGroupFromCAPI. If that synthesis fails (e.g. the Machine lacks required owner references, labels, or the kops cluster cannot be located from the Machine), the underlying error is wrapped with this message and the bootstrap request fails.
Source
Thrown at cmd/kops-controller/pkg/server/node_config.go:65
}
// CAPI path: the InstanceGroup is synthesized from the Machine and
// the name never reaches the configBase path, so we don't validate it.
} else if errs := kopsvalidation.ValidateInstanceGroupName(instanceGroupName, field.NewPath("instanceGroupName")); len(errs) > 0 {
return nil, fmt.Errorf("invalid InstanceGroup name: %v", errs.ToAggregate())
}
var nodeConfig *nodeup.NodeConfig
configBuilder := &commands.ConfigBuilder{
Clientset: s.clientset,
ClusterName: s.opt.ClusterName,
}
if identity.CAPIMachine != nil && instanceGroupName == "" {
// We have a CAPI Machine (but no instance group)
instanceGroup, err := s.buildInstanceGroupFromCAPI(ctx, identity.CAPIMachine)
if err != nil {
return nil, fmt.Errorf("error building InstanceGroup from CAPI Machine: %w", err)
}
log.Info("built InstanceGroup from CAPI Machine", "instanceGroup", instanceGroup)
configBuilder.InstanceGroup = instanceGroup
} else if s.opt.Cloud == "metal" {
configBuilder.InstanceGroupName = instanceGroupName
} else {
// Note: For now, we're assuming there is only a single cluster, and it is ours.
// We therefore use the configured base path
p := s.configBase.Join("igconfig", "node", instanceGroupName, "nodeupconfig.yaml")
b, err := p.ReadFile(ctx)
if err != nil {
return nil, fmt.Errorf("error loading NodeupConfig %q: %v", p, err)
}
nodeConfig = &nodeup.NodeConfig{}
nodeConfig.NodeupConfig = string(b)
}View on GitHub (pinned to 4c8573c808)
Solutions
- Read the wrapped inner error to see the concrete failure (missing label, not found, permissions) and fix that cause
- Ensure each CAPI Machine has the required cluster-name label and an ownerReference to the kops Cluster so buildInstanceGroupFromCAPI can resolve it
- Verify kops-controller can access the state store (configBase) and that the cluster spec is present
- Confirm the Machine belongs to the same cluster this kops-controller instance serves
Defensive patterns
Strategy: retry
Validate before calling
// pre-check the Machine carries the kops cluster-name label
if machine.Labels["kops.k8s.io/cluster"] == "" {
return fmt.Errorf("machine %s lacks kops cluster label", machine.Name)
} Try / catch
if strings.Contains(err.Error(), "error building InstanceGroup from CAPI Machine") {
// inspect wrapped cause; requeue the bootstrap with backoff after fixing labels/state store access
} Prevention
- Ensure CAPI Machines carry the kops.k8s.io/cluster label and Cluster ownerReferences
- Keep kops-controller and CAPI provider versions compatible
- Verify state store read access from kops-controller before rolling CAPI machines
When it happens
Trigger: identity.CAPIMachine != nil and instanceGroupName == "", and buildInstanceGroupFromCAPI returns an error — commonly because the Machine's cluster-name label or ownerReference to the Cluster is missing/unresolvable, or the referenced kops Cluster/InstanceGroup data cannot be fetched from state store.
Common situations: Machine objects created by a CAPI provider without the kops-required labels/annotations; CAPI Machine belonging to a different cluster than the one kops-controller serves; state store permissions or connectivity problems when reading cluster config; mismatched kops/clusterapi controller versions.
Related errors
- did not find owner for node %q
- node identity is required
- invalid InstanceGroup name: %v
- error loading NodeupConfig %q: %v
- CAPI Machine is missing cluster.x-k8s.io/deployment-name lab
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/4d8f7dece1257670.
Report an issue: GitHub.