kubernetes/kops · error
error fetching cluster %v: %w
Error message
error fetching cluster %v: %w
What it means
After reading `cluster.x-k8s.io/cluster-name` from the object's labels, getCAPIClusterFromCAPIObject fetches the referenced cluster.x-k8s.io/v1beta1 Cluster (unstructured) from the same namespace. This error wraps any failure of that kube.Get — almost always a NotFound because the label points to a Cluster that does not exist (or was deleted), but it can also be an API/server error or RBAC denial.
Source
Thrown at pkg/controllers/clusterapi/utils.go:80
}
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
}
func getKopsClusterFromCAPICluster(ctx context.Context, kube client.Client, capiCluster *unstructured.Unstructured) (*kopsapi.Cluster, error) {
var clusterKey types.NamespacedName
for _, ownerRef := range capiCluster.GetOwnerReferences() {
if ownerRef.Kind == "Cluster" && strings.HasPrefix(ownerRef.APIVersion, "kops.k8s.io/") {
clusterKey = types.NamespacedName{
Namespace: capiCluster.GetNamespace(),
Name: ownerRef.Name,
}
}
}
if clusterKey.Name == "" {View on GitHub (pinned to 4c8573c808)
Solutions
- Check the Cluster object exists: kubectl get cluster.x-k8s.io <name> -n <namespace>; recreate it if it was deleted
- Clean up orphaned dependent objects (machines, control planes) whose owning Cluster is gone
- Fix the `cluster.x-k8s.io/cluster-name` label value if it is misspelled or points to the wrong Cluster
- Install the cluster.x-k8s.io/v1beta1 Cluster CRD if missing (clusterctl init / apply CAPI core components)
- Verify RBAC allows the controller to get Clusters in the namespace
Example fix
# before: label references non-existent cluster
metadata:
labels:
cluster.x-k8s.io/cluster-name: deleted-cluster
# after: point label at an existing Cluster (or recreate the Cluster)
metadata:
labels:
cluster.x-k8s.io/cluster-name: my-existing-cluster Defensive patterns
Strategy: retry
Validate before calling
// check the target Cluster exists before dependent operations
key := types.NamespacedName{Namespace: obj.GetNamespace(), Name: obj.GetLabels()["cluster.x-k8s.io/cluster-name"]}
cluster := &unstructured.Unstructured{}
cluster.SetGroupVersionKind(schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "Cluster"})
err := kube.Get(ctx, key, cluster) // apierrors.IsNotFound(err) => stale label Type guard
func clusterExists(ctx context.Context, kube client.Client, ns, name string) bool {
c := &unstructured.Unstructured{}
c.SetGroupVersionKind(schema.GroupVersionKind{Group: "cluster.x-k8s.io", Version: "v1beta1", Kind: "Cluster"})
return kube.Get(ctx, types.NamespacedName{Namespace: ns, Name: name}, c) == nil
} Try / catch
capiCluster, err := getCAPIClusterFromCAPIObject(ctx, kube, obj)
if err != nil {
if apierrors.IsNotFound(errors.Unwrap(err)) {
// stale label or deleted cluster: drop orphaned object or requeue with backoff
return ctrl.Result{RequeueAfter: time.Minute}, nil
}
return ctrl.Result{}, err // transient API error: rely on reconcile retry
} Prevention
- Use ownerReferences/foreground deletion so dependents are cleaned up with their Cluster
- Watch for Cluster deletion events and garbage-collect labeled dependents
- Verify the cluster-name label value matches an actual Cluster name in the same namespace
- Ensure the controller has RBAC get on cluster.x-k8s.io clusters
When it happens
Trigger: Reconcile -> getCAPIClusterFromCAPIObject where the object is labeled `cluster.x-k8s.io/cluster-name: X` but no Cluster named X exists in the object's namespace, the API server is unreachable, or the controller's ServiceAccount lacks get permission on cluster.x-k8s.io Clusters.
Common situations: Dangling label after the CAPI Cluster was deleted while dependent objects remain (finalizers, orphaned machines); typo in the label value or wrong namespace; CRD cluster.x-k8s.io Clusters not installed; RBAC not granted to the controller.
Understand the failure class
Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.
Related errors
- label %q not set on %v
- clientset is not initialized
- could not get existing object: %w
- host not found for %v
- building kubernetes scheme: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/387cbfc572f2be6e.
Report an issue: GitHub.