{"record":{"id":"cb8b3f42fddb783b","repo":"kubernetes/kops","slug":"cannot-find-owner-for-instance-s","errorCode":null,"errorMessage":"cannot find owner for instance %s","messagePattern":"cannot find owner for instance (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/nodeidentity/gce/identify.go","lineNumber":148,"sourceCode":"\tvar capiMachine *clusterapi.Machine\n\n\tif i.capiManager != nil && capgRole != \"\" {\n\t\tproviderID := \"gce://\" + project + \"/\" + zone + \"/\" + instanceName\n\n\t\tm, err := i.capiManager.FindMachineByProviderID(ctx, providerID)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error finding Machine with providerID %q: %w\", providerID, err)\n\t\t}\n\t\tcapiMachine = m\n\t}\n\n\tvar igName string\n\tif capiMachine == nil {\n\t\t// The metadata itself is potentially mutable from the instance\n\t\t// We instead look at the MIG configuration\n\t\tcreatedBy := getMetadataValue(instance.Metadata, \"created-by\")\n\t\tif createdBy == \"\" {\n\t\t\treturn nil, fmt.Errorf(\"cannot find owner for instance %s\", instance.Name)\n\t\t}\n\n\t\t// We need to double-check the MIG configuration, in case created-by was changed\n\t\tmigName := lastComponent(createdBy)\n\n\t\tmig, err := i.getMIG(zone, migName)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\t// We now double check that the instance is indeed managed by the MIG\n\t\t// this can't be spoofed without GCE API access\n\t\tmigMember, err := i.getManagedInstance(ctx, mig, instance.Id)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tif migMember.Version == nil {","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/nodeidentity/gce/identify.go#L130-L166","documentation":"For non-CAPI instances, ownership (instance group name) is derived from the instance's \"created-by\" metadata, which points at the MIG that created it. If that metadata key is absent, there is no trustworthy way to determine which instance group owns the node, so identification fails. The metadata itself is mutable from the instance, hence the code deliberately trusts the MIG config instead.","triggerScenarios":"Calling IdentifyNode for a GCE instance with no CAPI role label whose metadata lacks the \"created-by\" key — typically instances not created by a MIG (standalone VMs, instances created by scripts/other tools) or with metadata stripped.","commonSituations":"Hand-created VMs manually added to a cluster; instances created by Terraform/ops tooling without MIG; metadata modified or lost after image/snapshot-based re-creation; very old clusters predating the created-by convention.","solutions":["Create the node via a Managed Instance Group (kops-managed IG) so GCE sets created-by automatically.","If the instance must stay standalone, add metadata: gcloud compute instances add-metadata <name> --zone <zone> --metadata created-by=<mig-uri>.","Check that the instance metadata server isn't disabled and metadata isn't being overwritten by startup scripts.","Verify the instance was not launched outside kops tooling — kops expects kops-managed instance groups."],"exampleFix":"// before — standalone instance without created-by\ninfo, err := id.IdentifyNode(ctx, node) // cannot find owner\n// after\n// gcloud compute instances add-metadata node-1 --zone us-central1-a \\\n//   --metadata created-by=https://www.googleapis.com/compute/v1/projects/p/zones/z/instanceGroupManagers/nodes-a-mig\ninfo, err := id.IdentifyNode(ctx, node)","handlingStrategy":"validation","validationCode":"createdBy := getMetadataValue(instance.Metadata, \"created-by\")\nif createdBy == \"\" {\n    return fmt.Errorf(\"instance %s has no created-by metadata; must be MIG-managed by kops\", instance.Name)\n}","typeGuard":"func hasCreatedByMetadata(inst *compute.Instance) bool {\n    return inst != nil && getMetadataValue(inst.Metadata, \"created-by\") != \"\"\n}","tryCatchPattern":"info, err := identifier.IdentifyNode(ctx, node)\nif err != nil && strings.Contains(err.Error(), \"cannot find owner\") {\n    // instance not kops/MIG-managed; exclude from kops-managed handling\n    return skipUnmanagedNode(node)\n}","preventionTips":["Only add nodes to clusters via kops-managed instance groups.","If adding standalone VMs, set created-by metadata manually.","Avoid startup scripts that wipe instance metadata.","Verify instance provenance (MIG vs manual) before registering."],"tags":["gce","kubernetes","node-identity","metadata","mig"],"backgroundTag":"missing-instance-metadata","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}