{"record":{"id":"4d8f7dece1257670","repo":"kubernetes/kops","slug":"error-building-instancegroup-from-capi-machine-w","errorCode":null,"errorMessage":"error building InstanceGroup from CAPI Machine: %w","messagePattern":"error building InstanceGroup from CAPI Machine: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/kops-controller/pkg/server/node_config.go","lineNumber":65,"sourceCode":"\t\t}\n\t\t// CAPI path: the InstanceGroup is synthesized from the Machine and\n\t\t// the name never reaches the configBase path, so we don't validate it.\n\t} else if errs := kopsvalidation.ValidateInstanceGroupName(instanceGroupName, field.NewPath(\"instanceGroupName\")); len(errs) > 0 {\n\t\treturn nil, fmt.Errorf(\"invalid InstanceGroup name: %v\", errs.ToAggregate())\n\t}\n\n\tvar nodeConfig *nodeup.NodeConfig\n\n\tconfigBuilder := &commands.ConfigBuilder{\n\t\tClientset:   s.clientset,\n\t\tClusterName: s.opt.ClusterName,\n\t}\n\n\tif identity.CAPIMachine != nil && instanceGroupName == \"\" {\n\t\t// We have a CAPI Machine (but no instance group)\n\t\tinstanceGroup, err := s.buildInstanceGroupFromCAPI(ctx, identity.CAPIMachine)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error building InstanceGroup from CAPI Machine: %w\", err)\n\t\t}\n\t\tlog.Info(\"built InstanceGroup from CAPI Machine\", \"instanceGroup\", instanceGroup)\n\t\tconfigBuilder.InstanceGroup = instanceGroup\n\t} else if s.opt.Cloud == \"metal\" {\n\t\tconfigBuilder.InstanceGroupName = instanceGroupName\n\t} else {\n\t\t// Note: For now, we're assuming there is only a single cluster, and it is ours.\n\t\t// We therefore use the configured base path\n\n\t\tp := s.configBase.Join(\"igconfig\", \"node\", instanceGroupName, \"nodeupconfig.yaml\")\n\n\t\tb, err := p.ReadFile(ctx)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error loading NodeupConfig %q: %v\", p, err)\n\t\t}\n\t\tnodeConfig = &nodeup.NodeConfig{}\n\t\tnodeConfig.NodeupConfig = string(b)\n\t}","sourceCodeStart":47,"sourceCodeEnd":83,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/cmd/kops-controller/pkg/server/node_config.go#L47-L83","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// pre-check the Machine carries the kops cluster-name label\nif machine.Labels[\"kops.k8s.io/cluster\"] == \"\" {\n\treturn fmt.Errorf(\"machine %s lacks kops cluster label\", machine.Name)\n}","typeGuard":null,"tryCatchPattern":"if strings.Contains(err.Error(), \"error building InstanceGroup from CAPI Machine\") {\n\t// inspect wrapped cause; requeue the bootstrap with backoff after fixing labels/state store access\n}","preventionTips":["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"],"tags":["kubernetes","kops","capi","bootstrap","instancegroup"],"backgroundTag":"capi-machine-synthesis-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}