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, errView on GitHub (pinned to 4c8573c808)
Solutions
- Ensure the instance was created by kops/CAPG with the instance-group-name metadata stamped
- If CAPG-managed, verify the instance has the CAPG role label and a matching Machine with the correct providerID
- Delete unauthorized instances — they should not join the cluster
- 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
- Only add nodes to the cluster via kops or CAPG; block direct VM joins
- Verify instance metadata is intact after any disk/image migration
- Keep CAPG Machine objects in sync with running VMs
- Treat ownership errors as security events and audit the instance
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
- incorrect Audience
- clusterName does not match expected: got %q, want %q
- failed to verify claim signature for node: %w
- failed to get GCE RSA attestation key from TPM: %w
- failed to marshal token data: %w
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/2bab65f25e933115.
Report an issue: GitHub.