kubernetes/kops · error

cannot find owner for instance %s

Error message

cannot find owner for instance %s

What it means

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.

Source

Thrown at pkg/nodeidentity/gce/identify.go:148

	var capiMachine *clusterapi.Machine

	if i.capiManager != nil && capgRole != "" {
		providerID := "gce://" + project + "/" + zone + "/" + instanceName

		m, err := i.capiManager.FindMachineByProviderID(ctx, providerID)
		if err != nil {
			return nil, fmt.Errorf("error finding Machine with providerID %q: %w", providerID, err)
		}
		capiMachine = m
	}

	var igName string
	if capiMachine == nil {
		// The metadata itself is potentially mutable from the instance
		// We instead look at the MIG configuration
		createdBy := getMetadataValue(instance.Metadata, "created-by")
		if createdBy == "" {
			return nil, fmt.Errorf("cannot find owner for instance %s", instance.Name)
		}

		// We need to double-check the MIG configuration, in case created-by was changed
		migName := lastComponent(createdBy)

		mig, err := i.getMIG(zone, migName)
		if err != nil {
			return nil, err
		}

		// We now double check that the instance is indeed managed by the MIG
		// this can't be spoofed without GCE API access
		migMember, err := i.getManagedInstance(ctx, mig, instance.Id)
		if err != nil {
			return nil, err
		}

		if migMember.Version == nil {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Create the node via a Managed Instance Group (kops-managed IG) so GCE sets created-by automatically.
  2. If the instance must stay standalone, add metadata: gcloud compute instances add-metadata <name> --zone <zone> --metadata created-by=<mig-uri>.
  3. Check that the instance metadata server isn't disabled and metadata isn't being overwritten by startup scripts.
  4. Verify the instance was not launched outside kops tooling — kops expects kops-managed instance groups.

Example fix

// before — standalone instance without created-by
info, err := id.IdentifyNode(ctx, node) // cannot find owner
// after
// gcloud compute instances add-metadata node-1 --zone us-central1-a \
//   --metadata created-by=https://www.googleapis.com/compute/v1/projects/p/zones/z/instanceGroupManagers/nodes-a-mig
info, err := id.IdentifyNode(ctx, node)
Defensive patterns

Strategy: validation

Validate before calling

createdBy := getMetadataValue(instance.Metadata, "created-by")
if createdBy == "" {
    return fmt.Errorf("instance %s has no created-by metadata; must be MIG-managed by kops", instance.Name)
}

Type guard

func hasCreatedByMetadata(inst *compute.Instance) bool {
    return inst != nil && getMetadataValue(inst.Metadata, "created-by") != ""
}

Try / catch

info, err := identifier.IdentifyNode(ctx, node)
if err != nil && strings.Contains(err.Error(), "cannot find owner") {
    // instance not kops/MIG-managed; exclude from kops-managed handling
    return skipUnmanagedNode(node)
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/cb8b3f42fddb783b. Report an issue: GitHub.