{"record":{"id":"272caa45b19892cd","repo":"kubernetes/kops","slug":"error-listing-machines-w","errorCode":null,"errorMessage":"error listing machines: %w","messagePattern":"error listing machines: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nodeidentity/clusterapi/capimanager/manager.go","lineNumber":54,"sourceCode":"func NewManager(kubeClient client.Client) *Manager {\n\treturn &Manager{\n\t\tkubeClient: kubeClient,\n\t}\n}\n\nfunc (m *Manager) FindMachineByProviderID(ctx context.Context, providerID string) (*clusterapi.Machine, error) {\n\t// TODO: Can we build an index\n\t// selector := client.MatchingFieldsSelector{\n\t// \tSelector: fields.OneTermEqualSelector(\"spec.providerID\", providerID),\n\t// }\n\tvar machines unstructured.UnstructuredList\n\tmachines.SetGroupVersionKind(schema.GroupVersionKind{\n\t\tGroup:   \"cluster.x-k8s.io\",\n\t\tKind:    \"Machine\",\n\t\tVersion: \"v1beta1\",\n\t})\n\tif err := m.kubeClient.List(ctx, &machines); err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing machines: %w\", err)\n\t}\n\tvar matches []*unstructured.Unstructured\n\tfor i := range machines.Items {\n\t\tmachine := &machines.Items[i]\n\t\tmachineSpecProviderID, _, _ := unstructured.NestedString(machine.Object, \"spec\", \"providerID\")\n\t\tif machineSpecProviderID != providerID {\n\t\t\tcontinue\n\t\t}\n\t\tmatches = append(matches, machine)\n\t}\n\tif len(matches) > 0 {\n\t\tif len(matches) > 1 {\n\t\t\treturn nil, fmt.Errorf(\"found multiple machines with providerID %q\", providerID)\n\t\t}\n\t\tmachine := matches[0]\n\t\tmachine = machine.DeepCopy()\n\t\treturn clusterapi.NewMachine(machine), nil\n\t}","sourceCodeStart":36,"sourceCodeEnd":72,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/nodeidentity/clusterapi/capimanager/manager.go#L36-L72","documentation":"In the Cluster API nodeidentity manager, FindMachineByProviderID lists all cluster.x-k8s.io/v1beta1 Machine objects via the controller-runtime client. If the List call against the management cluster fails, the error is wrapped as \"error listing machines\". The root cause is the wrapped client error: RBAC denial, unreachable API server, or CRD/mismatched API version.","triggerScenarios":"Calling FindMachineByProviderID (via IdentifyNode or VerifyToken) when the management cluster API server is unreachable, the caller's ServiceAccount lacks list/get on cluster.x-k8s.io/machines, or the Cluster API CRDs (v1beta1) are not installed.","commonSituations":"Running the node identity service outside the management cluster with stale kubeconfig; missing RBAC rules in the CAPI provider's ClusterRole; upgrading Cluster API from v1alpha3/v1alpha4 to v1beta1 while CRDs are still old; network policy blocking egress to the API server.","solutions":["Read the wrapped error: for 'forbidden', add RBAC (list/get machines.cluster.x-k8s.io) to the caller's ServiceAccount.","Verify Cluster API CRDs v1beta1 exist in the management cluster (kubectl get crd machines.cluster.x-k8s.io).","Confirm kubeconfig/connectivity from the component to the management cluster API server.","Retry on transient connection errors; check API server health and rate limits."],"exampleFix":"// before: ServiceAccount with no CAPI permissions\nkind: ClusterRole\nrules: []\n\n// after\nkind: ClusterRole\nrules:\n- apiGroups: [\"cluster.x-k8s.io\"]\n  resources: [\"machines\"]\n  verbs: [\"get\", \"list\", \"watch\"]","handlingStrategy":"retry","validationCode":"if err := kubeClient.List(ctx, &client.ListOptions{Limit: 1}, &unstructured.UnstructuredList{}); err != nil {\n    return fmt.Errorf(\"management cluster unreachable / RBAC denied: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"machine, err := mgr.FindMachineByProviderID(ctx, providerID)\nif err != nil && strings.Contains(err.Error(), \"error listing machines\") {\n    if apierrors.IsForbidden(err) {\n        return fmt.Errorf(\"grant list on machines.cluster.x-k8s.io to the ServiceAccount: %w\", err)\n    }\n    return retryWithBackoff(3, func() error {\n        machine, err = mgr.FindMachineByProviderID(ctx, providerID)\n        return err\n    })\n}","preventionTips":["Provision RBAC (get/list/watch machines.cluster.x-k8s.io) with the component's manifests","Deploy the component inside the management cluster or refresh kubeconfigs automatically","Verify CAPI CRDs are v1beta1 after every Cluster API upgrade"],"tags":["clusterapi","kubernetes","rbac","list-machines","kops"],"backgroundTag":"kubernetes-api-list-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}