kubernetes/kops · error

failed to retrieve droplet %d: %w

Error message

failed to retrieve droplet %d: %w

What it means

IdentifyNode calls doClient.Droplets.Get to fetch the droplet by numeric ID. If the DigitalOcean API returns an error (auth failure, rate limit, network error, or API-side not-found), the error is wrapped with the droplet ID using %w.

Source

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

		return nil, errors.New("provider ID number cannot be empty")
	}

	if i.cacheEnabled {
		if obj, exists, err := i.cache.GetByKey(instanceID); err != nil {
			klog.Warningf("Nodeidentity info cache lookup failure: %v", err)
		} 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)
		}
	}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped cause (%w) for the HTTP status — 401/403 means fix the API token, 429 means back off, 404 means the droplet is gone
  2. Verify the digitalocean token credential is valid and has read scope for droplets
  3. Check DigitalOcean API status and retry with backoff if rate-limited or during an outage
  4. If the droplet was deleted, remove the stale Node object from the cluster
Defensive patterns

Strategy: retry

Validate before calling

// verify credentials before calling
token := os.Getenv("DIGITALOCEAN_ACCESS_TOKEN")
if token == "" { return errors.New("missing DO token") }

Try / catch

info, err := IdentifyNode(ctx, providerID)
if err != nil {
    var apiErr *goauthorize.Error
    if errors.As(err, &apiErr) {
        switch {
        case apiErr.StatusCode == 429: // backoff and retry
        case apiErr.StatusCode == 401: // refresh/fix token
        default: // alert on API outage
        }
    }
}

Prevention

When it happens

Trigger: DigitalOcean API call fails: invalid/expired API token, rate limiting (429), network outage, or the droplet was deleted (404 surfaced by the API client as an error).

Common situations: Expired or revoked DO API token on the controller; DO API rate limits hit at scale; droplet deleted between providerID assignment and lookup; regional API outage.

Related errors


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