kubernetes/kops · error

instance %v not managed by mig %s

Error message

instance %v not managed by mig %s

What it means

The MIG member listing succeeded, but none of the group's instances had the instance ID reported by the kubelet, so kops concludes the node is not actually managed by this MIG. It signals an identity mismatch between the cluster Node object and the GCE instance group.

Source

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

	var matches []*compute.ManagedInstance

	filter := "id=" + strconv.FormatUint(instanceID, 10)
	zone := lastComponent(mig.Zone)
	if err := i.computeService.InstanceGroupManagers.ListManagedInstances(i.project, zone, mig.Name).Filter(filter).Pages(ctx, func(page *compute.InstanceGroupManagersListManagedInstancesResponse) error {
		// Post-filter... filters aren't implemented (b/27605549)
		for _, instance := range page.ManagedInstances {
			if instance.Id != instanceID {
				continue
			}
			matches = append(matches, instance)
		}
		return nil
	}); err != nil {
		return nil, fmt.Errorf("error fetching GCE managed instance group members for %q: %v", mig.Name, err)
	}

	if len(matches) == 0 {
		return nil, fmt.Errorf("instance %v not managed by mig %s", instanceID, mig.Name)
	}
	if len(matches) > 1 {
		// Should be impossible - shows that filters / post-filters are not working
		return nil, fmt.Errorf("found multiple instances with id %v managed by mig %s", instanceID, mig.Name)
	}

	return matches[0], nil
}

// lastComponent returns the last component of a URL, i.e. anything after the last slash
// If there is no slash, returns the whole string
func lastComponent(s string) string {
	lastSlash := strings.LastIndex(s, "/")
	if lastSlash != -1 {
		s = s[lastSlash+1:]
	}
	return s
}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Delete the stale Node object (kubectl delete node <name>) so it is re-registered
  2. Verify the instance is a MIG member: gcloud compute instance-groups managed list-instances <mig> --zone <zone>
  3. Ensure the node was created by the MIG, not manually (kops create instance-group + update)
  4. Re-check that the instance ID from node metadata matches a current MIG member

Example fix

// before: error only
// after: operator remediation
case strings.Contains(err.Error(), "not managed by mig"):
  // node is stale/unmanaged; remove and let MIG recreate it
  client.CoreV1().Nodes().Delete(ctx, node.Name, metav1.DeleteOptions{})
Defensive patterns

Strategy: fallback

Validate before calling

members, _ := migMembers(mig); containsInstanceID(members, instanceID) // precheck membership

Try / catch

info, err := IdentifyNode(ctx, node)
if err != nil && strings.Contains(err.Error(), "not managed by mig") {
  // stale/unmanaged node: delete Node object, skip
}

Prevention

When it happens

Trigger: After filtering MIG members by their instance ID, len(matches)==0: the node's reported instance ID belongs to an instance that left the MIG, was deleted, or the node is a non-MIG instance misreporting membership.

Common situations: Node replaced in a rolling update while the old Node object still exists; instance recreated outside the MIG (unmanaged); stale Node objects after MIG resize-down; instance ID changed after stop/start.

Related errors


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