kubernetes/kops · error
instance %s did not have Version set
Error message
instance %s did not have Version set
What it means
For MIG-owned instances, IdentifyNode reads the MIG member's currentVersion/Version to find the instance template that defines the group. If the ManagedInstance's Version field is nil (GCE did not populate it), the template cannot be resolved and identification fails.
Source
Thrown at pkg/nodeidentity/gce/identify.go:167
}
// 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 {
return nil, fmt.Errorf("instance %s did not have Version set", instance.Name)
}
instanceTemplate, err := i.getInstanceTemplate(lastComponent(migMember.Version.InstanceTemplate))
if err != nil {
return nil, err
}
igName = getMetadataValue(instanceTemplate.Properties.Metadata, MetadataKeyInstanceGroupName)
if igName == "" {
return nil, fmt.Errorf("ig name not set on instance template %s", instanceTemplate.Name)
}
}
info := &nodeidentity.Info{}
// info.InstanceID TODO: InstanceID is only used by the provider?
tagToRole := make(map[string]kops.InstanceGroupRole)
for _, role := range kops.AllInstanceGroupRoles {View on GitHub (pinned to 4c8573c808)
Solutions
- Retry after the MIG update completes (TRANSIENT): check `gcloud compute instance-groups managed describe <mig> --zone <zone>` until all instances have a currentVersion.
- Recreate the MIG with a versioned instance template (gcloud compute instance-groups managed set-instance-template) so each member reports a Version.
- If the member is stuck, use recreate-instances on the MIG for that instance.
- Ensure the compute API version in use populates Version; upgrade kops/GCE client if using legacy fields.
Example fix
// before
if migMember.Version == nil { return nil, fmt.Errorf("instance %s did not have Version set", instance.Name) }
// after — retry with backoff while MIG settles
var tmpl string
err := wait.ExponentialBackoff(backoff, func() (bool, error) {
m, err := i.getManagedInstance(ctx, mig, instance.Id)
if err != nil { return false, nil }
if m.Version == nil { return false, nil }
tmpl = lastComponent(m.Version.InstanceTemplate)
return true, nil
}) Defensive patterns
Strategy: retry
Validate before calling
migMember, err := getManagedInstance(ctx, mig, instance.Id)
if err == nil && migMember.Version == nil {
return fmt.Errorf("MIG member %d has no version yet; MIG update in progress, retry", instance.Id)
} Type guard
func hasVersion(m *compute.ManagedInstance) bool {
return m != nil && m.Version != nil && m.Version.InstanceTemplate != ""
} Try / catch
info, err := identifier.IdentifyNode(ctx, node)
if err != nil && strings.Contains(err.Error(), "did not have Version set") {
// transient during MIG rolling updates: retry with backoff
return requeueWithBackoff(err)
} Prevention
- Avoid identifying nodes while kops rolling-update is actively replacing them.
- Use versioned instance templates on all MIGs (not legacy template-only MIGs).
- Add backoff/retry around identification.
- Monitor MIG status until stable before running identification-dependent jobs.
When it happens
Trigger: getManagedInstance returns a compute.ManagedInstance whose Version is nil — seen with MIGs created by very old API versions, MIGs mid-update where targetDistribution state is odd, or instances being recreated/abandoned during a MIG update.
Common situations: MIG in the middle of an autohealing/rolling-update action; MIG created without versioned templates (legacy instanceTemplate-only MIGs); transient GCE API responses during instance recreation.
Related errors
- ig name not set on instance template %s
- found instance %q, but status is %q
- cannot find owner for instance %s
- error fetching GCE managed instance group %q: %v
- providerID was not set for node %s
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/b887eff388081f11.
Report an issue: GitHub.