kubernetes/kops · warning
found instance %q, but status is %q
Error message
found instance %q, but status is %q
What it means
After fetching the instance from the GCE API, IdentifyNode only proceeds if the instance status is "RUNNING". Instances in PROVISIONING, STAGING, TERMINATED, or STOPPED states cannot be reliably identified (labels/metadata may be incomplete or the node is going away), so the identification is aborted with this message.
Source
Thrown at pkg/nodeidentity/gce/identify.go:125
return nil, fmt.Errorf("providerID %q not recognized for node %s", providerID, node.Name)
}
project := tokens[0]
zone := tokens[1]
instanceName := tokens[2]
if project != i.project {
return nil, fmt.Errorf("providerID %q did not match our project %q", providerID, i.project)
}
instance, err := i.getInstance(zone, instanceName)
if err != nil {
return nil, err
}
instanceStatus := instance.Status
if instanceStatus != "RUNNING" {
return nil, fmt.Errorf("found instance %q, but status is %q", instanceName, instanceStatus)
}
capgRole := instance.Labels[LabelKeyCAPIRoleName]
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 {View on GitHub (pinned to 4c8573c808)
Solutions
- Re-run identification once the instance is RUNNING (TRANSIENT — wait/retry, e.g. with backoff).
- If the instance is TERMINATED and the node should be gone, delete the stale Node object instead of identifying it.
- For preemptible/spot instances, expect frequent restarts and handle this error by requeueing.
- Check GCE console / `gcloud compute instances describe <name> --zone <zone> --format='value(status)'` to see actual state and why.
Example fix
// before
info, err := id.IdentifyNode(ctx, node) // instance still PROVISIONING
// after
err := wait.PollImmediate(5*time.Second, 2*time.Minute, func() (bool, error) {
_, err := id.IdentifyNode(ctx, node)
return err == nil, nil // retry until instance is RUNNING
}) Defensive patterns
Strategy: retry
Validate before calling
status, err := computeSvc.Instances.Get(project, zone, instanceName).Do()
if err == nil && status.Status != "RUNNING" {
return fmt.Errorf("instance %s not ready (status %s); retry later", instanceName, status.Status)
} Type guard
func isRunning(inst *compute.Instance) bool {
return inst != nil && inst.Status == "RUNNING"
} Try / catch
info, err := identifier.IdentifyNode(ctx, node)
if err != nil && strings.Contains(err.Error(), "but status is") {
// transient: instance starting/stopping; requeue with backoff
return requeueAfter(30 * time.Second)
} Prevention
- Requeue identification with backoff for non-RUNNING instances.
- Treat TERMINATED instances as signals to delete the stale Node object.
- Expect frequent restarts with preemptible/spot VMs and handle gracefully.
- Check instance status via gcloud before debugging deeper.
When it happens
Trigger: Calling IdentifyNode for a node whose GCE instance exists but whose Status field returned by compute.Instances.Get is anything other than "RUNNING" — e.g. the instance is being deleted, stopped, or just starting.
Common situations: Node deleted concurrently with identification (autoscaler scale-down); instance stopped manually or preempted; a Node object lingering in the k8s API after its VM was terminated; race where kubelet registered before the instance reached RUNNING.
Related errors
- providerID was not set for node %s
- providerID %q not recognized for node %s
- providerID %q did not match our project %q
- cannot find owner for instance %s
- instance %s did not have Version set
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/a30063a7b1ccc2e8.
Report an issue: GitHub.