kubernetes/kops · error

droplet %d has unexpected status %q

Error message

droplet %d has unexpected status %q

What it means

The droplet was found but its status is neither 'active' nor 'new'. IdentifyNode only accepts droplets that are usable or still provisioning; intermediate states (off, archive, etc.) are rejected because the node identity cannot be trusted for a non-running droplet.

Source

Thrown at pkg/nodeidentity/do/identify.go:156

		} else if exists {
			return obj.(*nodeidentity.Info), nil
		}
	}

	dropletID, err := strconv.Atoi(instanceID)
	if err != nil {
		return nil, fmt.Errorf("failed to convert provider ID number %q: %s", instanceID, err)
	}

	droplet, _, err := i.doClient.Droplets.Get(ctx, dropletID)
	if err != nil {
		return nil, fmt.Errorf("failed to retrieve droplet %d: %w", dropletID, err)
	}
	if droplet == nil {
		return nil, fmt.Errorf("droplet %d not found", dropletID)
	}
	if droplet.Status != "active" && droplet.Status != "new" {
		return nil, fmt.Errorf("droplet %d has unexpected status %q", dropletID, droplet.Status)
	}

	info := &nodeidentity.Info{
		InstanceID: instanceID,
		Labels:     labelsFromTags(droplet.Tags),
	}

	if i.cacheEnabled {
		if err := i.cache.Add(info); err != nil {
			klog.Warningf("Failed to add node identity info to cache: %v", err)
		}
	}

	return info, nil
}

// labelsFromTags derives node labels from a droplet's tags.
//

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Power the droplet back on (doctl compute droplet-action poweron <id> or via the console) so its status becomes 'active'
  2. Wait for any in-progress action (resize/restore/rebuild) to finish and the status to settle to 'active'
  3. Check droplet action history for failed operations leaving it in an odd state
  4. If the machine is permanently decommissioned, remove the stale Node from the cluster
Defensive patterns

Strategy: type-guard

Validate before calling

if droplet.Status != "active" && droplet.Status != "new" {
    return fmt.Errorf("droplet not ready: %s", droplet.Status)
}

Type guard

func dropletUsable(d *godo.Droplet) bool {
    return d != nil && (d.Status == "active" || d.Status == "new")
}

Try / catch

info, err := IdentifyNode(ctx, providerID)
if err != nil {
    if strings.Contains(err.Error(), "unexpected status") {
        // power on the droplet or wait for its action to complete, then retry
    }
}

Prevention

When it happens

Trigger: Droplet.Status is e.g. 'off' after a shutdown/power-cycle, or another transitional state when the node identity lookup runs.

Common situations: Droplet powered off manually or via autoscaling/reschedule; droplet stuck in a transitional state after a failed resize or snapshot restore; node object outliving a powered-down machine.

Related errors


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