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

  1. Set spec.failureDomain on the CAPI Machine (e.g. the AZ/zone)
  2. Update the MachineDeployment/MachineSet template to include failureDomain
  3. 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

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


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