kubernetes/kops · critical

could not determine ownership for instance %s

Error message

could not determine ownership for instance %s

What it means

VerifyToken cannot attribute the instance to this cluster: it has neither the kops instance-group metadata item (a kops-managed instance) nor a matching CAPI Machine (a CAPG-managed instance). The verifier refuses to issue credentials for instances it cannot prove ownership of.

Source

Thrown at upup/pkg/fi/cloudup/gce/tpm/gcetpmverifier/tpmverifier.go:176

	if clusterName != v.opt.ClusterName {
		return nil, fmt.Errorf("clusterName does not match expected: got %q, want %q", clusterName, v.opt.ClusterName)
	}

	var capiMachine *clusterapi.Machine

	if v.capiManager != nil && capgRole != "" {
		providerID := "gce://" + tokenData.GCPProjectID + "/" + tokenData.Zone + "/" + tokenData.Instance

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

	// Check if this is a CAPG managed instance
	if instanceGroupName == "" && capiMachine == nil {
		return nil, fmt.Errorf("could not determine ownership for instance %s", instance.SelfLink)
	}

	// Verify the token has a valid GCE TPM signature.
	{
		// Note - we might be able to avoid this call by including the attestation certificate (signed by GCE) in the claim.
		tpmSigningKey, err := v.getTPMSigningKey(ctx, &tokenData)
		if err != nil {
			return nil, err
		}

		if !verifySignature(tpmSigningKey, token.Data, token.Signature) {
			return nil, fmt.Errorf("failed to verify claim signature for node: %w", err)
		}
	}

	sans, err := GetInstanceCertificateAlternateNames(instance)
	if err != nil {
		return nil, err

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Ensure the instance was created by kops/CAPG with the instance-group-name metadata stamped
  2. If CAPG-managed, verify the instance has the CAPG role label and a matching Machine with the correct providerID
  3. Delete unauthorized instances — they should not join the cluster
  4. If a rebuilt instance lost metadata, recreate it via kops rolling-update
Defensive patterns

Strategy: validation

Validate before calling

inst, _ := computeClient.Instances.Get(proj, zone, name).Do()
hasIG := false
for _, it := range inst.Metadata.Items {
    if it.Key == "instance-group-name" && fi.ValueOf(it.Value) != "" { hasIG = true }
}
if !hasIG && inst.Labels["capg-role"] == "" {
    return fmt.Errorf("instance %s has no kops or CAPG ownership markers", name)
}

Prevention

When it happens

Trigger: Instance has an empty instance-group-name metadata item AND either capiManager is nil / the CAPG role label is absent, or FindMachineByProviderID returned no Machine — i.e. an instance whose ownership path is unresolvable.

Common situations: A hand-created or imported VM trying to join the cluster; instance metadata stripped (e.g. copied disk or custom image without kops metadata); a CAPG machine deleted from the management cluster while the VM persists; non-CAPG nodes when capiManager is configured to require CAPG.

Related errors


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