{"record":{"id":"c2b89cf8287187ef","repo":"kubernetes/kops","slug":"providerid-was-not-set-for-node-s-c2b89c","errorCode":null,"errorMessage":"providerID was not set for node %s","messagePattern":"providerID was not set for node (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nodeidentity/gce/identify.go","lineNumber":99,"sourceCode":"\t\t}\n\t\tklog.Infof(\"Found project=%q\", project)\n\t}\n\n\treturn &nodeIdentifier{\n\t\tcomputeService: computeService,\n\t\tproject:        project,\n\t\tclusterName:    clusterName,\n\t\tcapiManager:    capiManager,\n\t}, nil\n}\n\n// IdentifyNode queries GCE for the node identity information\nfunc (i *nodeIdentifier) IdentifyNode(ctx context.Context, node *corev1.Node) (*nodeidentity.Info, error) {\n\t// log := klog.FromContext(ctx)\n\n\tproviderID := node.Spec.ProviderID\n\tif providerID == \"\" {\n\t\treturn nil, fmt.Errorf(\"providerID was not set for node %s\", node.Name)\n\t}\n\tif !strings.HasPrefix(providerID, \"gce://\") {\n\t\treturn nil, fmt.Errorf(\"providerID %q not recognized for node %s\", providerID, node.Name)\n\t}\n\n\ttokens := strings.Split(strings.TrimPrefix(providerID, \"gce://\"), \"/\")\n\tif len(tokens) != 3 {\n\t\treturn nil, fmt.Errorf(\"providerID %q not recognized for node %s\", providerID, node.Name)\n\t}\n\n\tproject := tokens[0]\n\tzone := tokens[1]\n\tinstanceName := tokens[2]\n\n\tif project != i.project {\n\t\treturn nil, fmt.Errorf(\"providerID %q did not match our project %q\", providerID, i.project)\n\t}\n","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/nodeidentity/gce/identify.go#L81-L117","documentation":"IdentifyNode resolves a Kubernetes Node to GCE instance identity info. It requires node.Spec.ProviderID to be set, because all subsequent lookups (project/zone/instance parsing and GCE API queries) derive from that string. If the providerID field is empty, there is nothing to identify the node with, so it fails fast.","triggerScenarios":"Calling IdentifyNode (directly or via the node-authorizer/identity controller) with a *corev1.Node whose Spec.ProviderID is \"\" — typically because the cloud-controller-manager or kubelet never populated it.","commonSituations":"Nodes registered by kubelet before the cloud provider integration set the provider ID; clusters where --cloud-provider=external is misconfigured so the GCE cloud controller never patches node.Spec.ProviderID; manually created Node objects in tests or fixtures; node objects restored from etcd backups missing spec updates.","solutions":["Ensure the GCE cloud-controller-manager is running and has annotated/patched the Node (check that node.spec.providerID looks like gce://project/zone/instance-name).","Wait for node initialization: newly joined nodes get their providerID set shortly after registration; re-run identification after reconciliation.","If constructing the Node yourself (tests/tools), set Spec.ProviderID explicitly to \"gce://<project>/<zone>/<instance>\".","Check kubelet flags: on GCE the kubelet/cloud provider must not run with --cloud-provider=none, which skips providerID assignment."],"exampleFix":"// before\nnode := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: \"gke-node-1\"}}\ninfo, err := identifier.IdentifyNode(ctx, node) // errors: providerID was not set\n// after\nnode := &corev1.Node{ObjectMeta: metav1.ObjectMeta{Name: \"gke-node-1\"}, Spec: corev1.NodeSpec{ProviderID: \"gce://my-project/us-central1-a/gke-node-1\"}}\ninfo, err := identifier.IdentifyNode(ctx, node)","handlingStrategy":"validation","validationCode":"if node.Spec.ProviderID == \"\" {\n    return fmt.Errorf(\"skip node %s: providerID not yet set\", node.Name)\n}\n_ = identifier.IdentifyNode(ctx, node)","typeGuard":"func hasProviderID(node *corev1.Node) bool {\n    return node != nil && node.Spec.ProviderID != \"\"\n}","tryCatchPattern":"info, err := identifier.IdentifyNode(ctx, node)\nif err != nil {\n    if strings.Contains(err.Error(), \"providerID was not set\") {\n        // requeue: providerID usually appears shortly after node registration\n        return requeueAfter(10 * time.Second)\n    }\n    return err\n}","preventionTips":["Run the GCE cloud-controller-manager so providerID is always set on node registration.","Before identifying, wait/poll until node.Spec.ProviderID is non-empty.","Skip or requeue nodes lacking providerID instead of failing hard.","In tests/fixtures, always populate Spec.ProviderID."],"tags":["gce","kubernetes","node-identity","providerid"],"backgroundTag":"missing-provider-id","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"}