kubernetes/kops · error
label %q not set on %v
Error message
label %q not set on %v
What it means
getCAPIClusterFromCAPIObject resolves the parent cluster.x-k8s.io Cluster for any CAPI object by reading the well-known `cluster.x-k8s.io/cluster-name` label. This error is thrown when the object passed in (e.g. a Machine, MachineDeployment, or KopsControlPlane) has no value for that label, so the owning CAPI Cluster cannot be determined from the object alone.
Source
Thrown at pkg/controllers/clusterapi/utils.go:66
{
APIVersion: apiVersion,
Kind: kind,
Name: owner.GetName(),
UID: owner.GetUID(),
Controller: new(true),
},
})
}
func getCAPIClusterFromCAPIObject(ctx context.Context, kube client.Client, obj client.Object) (*unstructured.Unstructured, error) {
id := types.NamespacedName{
Namespace: obj.GetNamespace(),
Name: obj.GetName(),
}
capiClusterName := obj.GetLabels()[clusterv1.ClusterNameLabel]
if capiClusterName == "" {
return nil, fmt.Errorf("label %q not set on %v", clusterv1.ClusterNameLabel, id)
}
capiCluster := &unstructured.Unstructured{}
capiCluster.SetGroupVersionKind(schema.GroupVersionKind{
Group: "cluster.x-k8s.io",
Version: "v1beta1",
Kind: "Cluster",
})
clusterKey := types.NamespacedName{
Namespace: obj.GetNamespace(),
Name: capiClusterName,
}
if err := kube.Get(ctx, clusterKey, capiCluster); err != nil {
return nil, fmt.Errorf("error fetching cluster %v: %w", clusterKey, err)
}
return capiCluster, nil
}View on GitHub (pinned to 4c8573c808)
Solutions
- Add the label `cluster.x-k8s.io/cluster-name: <capi-cluster-name>` to the affected object
- Recreate the resource through the CAPI Cluster topology (e.g. via the ClusterClass or machine deployment) so CAPI sets the label itself
- Check cluster-api version — objects provisioned by very old CAPI releases may lack the label and need upgrading/patching
- Verify the reconciler is watching objects that belong to a CAPI-managed cluster at all
Example fix
// before (object missing label)
metadata:
name: my-machine
kind: Machine
// after
metadata:
name: my-machine
kind: Machine
labels:
cluster.x-k8s.io/cluster-name: my-cluster Defensive patterns
Strategy: validation
Validate before calling
const ClusterNameLabel = "cluster.x-k8s.io/cluster-name"
func hasClusterNameLabel(obj client.Object) bool {
return obj.GetLabels()[ClusterNameLabel] != ""
}
// before reconciling:
if !hasClusterNameLabel(obj) {
// skip / requeue instead of calling getCAPIClusterFromCAPIObject
} Type guard
func extractCAPIClusterName(obj client.Object) (string, bool) {
name, ok := obj.GetLabels()["cluster.x-k8s.io/cluster-name"]
if !ok || name == "" {
return "", false
}
return name, true
} Prevention
- Always create CAPI-managed resources via cluster-api tooling so the cluster-name label is applied automatically
- Validate manifests with a policy tool (Kyverno/OPA) requiring cluster.x-k8s.io/cluster-name on Machines and control planes
- When copying CAPI object YAML, preserve metadata.labels
- Add a CI check that adopted objects carry the required CAPI labels
When it happens
Trigger: Reconcile calls getCAPIClusterFromCAPIObject with an object whose GetLabels()[clusterv1.ClusterNameLabel] returns "" — the `cluster.x-k8s.io/cluster-name` label is absent or empty on the reconciled resource.
Common situations: Resources created manually or by tooling that does not apply CAPI's standard topology labels; resources from an older CAPI version predating the label; hand-copied YAML missing metadata.labels; objects adopted from non-CAPI management.
Related errors
- cluster name label %q not yet set
- error fetching cluster %v: %w
- clientset is not initialized
- CAPI Machine is missing cluster.x-k8s.io/deployment-name lab
- building kubernetes scheme: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/8661bcb097525543.
Report an issue: GitHub.