kubernetes/kops · error
CAPI Machine is missing spec.failureDomain
Error message
CAPI Machine is missing spec.failureDomain
What it means
The CAPI Machine must declare spec.failureDomain so kOps can place it in the right zone/failure domain when reconstructing the InstanceGroup. This error is thrown when GetFailureDomain() returns an empty string.
Source
Thrown at cmd/kops-controller/pkg/server/node_config.go:129
}
}
return nodeConfig, nil
}
// buildInstanceGroupFromCAPI builds an InstanceGroup from a CAPI Machine, for building bootstrap data.
// It builds a minimal instanceGroup, because many fields (e.g. image, machineType, minSize, maxSize)
// are not relevant for building the bootstrap data.
func (s *Server) buildInstanceGroupFromCAPI(ctx context.Context, capiMachine *clusterapi.Machine) (*kops.InstanceGroup, error) {
log := klog.FromContext(ctx)
capiDeploymentName := capiMachine.GetDeploymentName()
if capiDeploymentName == "" {
return nil, fmt.Errorf("CAPI Machine is missing cluster.x-k8s.io/deployment-name label")
}
failureDomain := capiMachine.GetFailureDomain()
if failureDomain == "" {
return nil, fmt.Errorf("CAPI Machine is missing spec.failureDomain")
}
ig := &kops.InstanceGroup{}
ig.Labels = map[string]string{
// kops.LabelClusterName: cluster.Name, // Should not matter
}
ig.Name = capiDeploymentName
// "maxSize": 1, // Should not matter
// "minSize": 1, // Should not matter
// "machineType": "", // Should not matter
// "subnets": // Should not matter
ig.Spec.Zones = []string{failureDomain}
ig.Spec.Role = "Node" // TODO: Support other roles?
// The machine image is chosen by the CAPI infrastructure provider and is not used for
// nodeup config generation; the placeholder avoids resolving a default from the channel.
ig.Spec.Image = "placeholder-image"
View on GitHub (pinned to 4c8573c808)
Solutions
- Set spec.failureDomain on the CAPI Machine (e.g. the AZ/zone)
- Update the MachineDeployment/MachineSet template to include failureDomain
- Recreate the Machine through the kOps-managed machine deployment
Example fix
// before
spec: {}
// after
spec:
failureDomain: us-east-1a Defensive patterns
Strategy: validation
Validate before calling
if m.Spec.FailureDomain == nil || *m.Spec.FailureDomain == "" {
return fmt.Errorf("machine %s missing spec.failureDomain", m.Name)
} Type guard
func hasFailureDomain(m *capi.Machine) bool {
return m.GetFailureDomain() != ""
} Prevention
- Set spec.failureDomain in MachineDeployment templates
- Create Machines only through kOps-generated MachineDeployments
- Validate machine manifests with admission policies
When it happens
Trigger: A bootstrap request from a CAPI Machine whose spec.failureDomain is unset or empty.
Common situations: Machine created directly (not by a kOps-generated MachineDeployment) without failureDomain; cloud provider doesn't populate it; template authored manually omitting spec.failureDomain.
Related errors
- CAPI Machine is missing cluster.x-k8s.io/deployment-name lab
- did not find owner for node %q
- error building InstanceGroup from CAPI Machine: %w
- node identity is required
- error loading NodeupConfig %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/6ce2cfe6f9a71cbb.
Report an issue: GitHub.