kubernetes/kops · error
failed to list vpcs: %v
Error message
failed to list vpcs: %v
What it means
listVPCs wraps any failure from the DigitalOcean API client's GetAllVPCs() call. The library throws it when the underlying godo VPC list request fails (auth, network, API error), aborting discovery of the cluster's 'vpc-<clustername>' VPC resource. The original API error is embedded via %v.
Source
Thrown at pkg/resources/digitalocean/resources.go:462
if response != nil && response.StatusCode == http.StatusNotFound {
return nil
}
return fmt.Errorf("failed to delete ssh key %s (ID %s): %s", t.Name, t.ID, err)
}
return nil
}
func listVPCs(cloud fi.Cloud, clusterName string) ([]*resources.Resource, error) {
c := cloud.(do.DOCloud)
var resourceTrackers []*resources.Resource
clusterName = do.SafeClusterName(clusterName)
vpcName := "vpc-" + clusterName
vpcs, err := c.GetAllVPCs()
if err != nil {
return nil, fmt.Errorf("failed to list vpcs: %v", err)
}
for _, vpc := range vpcs {
if vpc.Name == vpcName {
resourceTracker := &resources.Resource{
Name: vpc.Name,
ID: vpc.ID,
Type: resourceTypeVPC,
Deleter: deleteVPC,
Obj: vpc,
}
resourceTrackers = append(resourceTrackers, resourceTracker)
}
}
return resourceTrackers, nil
}View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the DigitalOcean API token is valid and has read scope (doctl auth check or curl -H 'Authorization: Bearer <token>' https://api.digitalocean.com/v2/vpcs).
- Inspect the wrapped inner error (%v output) for the real cause: 401 => bad token, 429 => rate limited, 5xx/timeout => DO outage; fix accordingly.
- Check network/proxy connectivity from the machine running kops to api.digitalocean.com (DNS, firewall, HTTPS_PROXY settings).
- If rate-limited, wait for the rate-limit window to reset and retry; if it's a transient DO incident, retry after api.status.digitalocean.com shows healthy.
Example fix
// before
vpcs, err := c.GetAllVPCs()
if err != nil {
return nil, fmt.Errorf("failed to list vpcs: %v", err)
}
// after
vpcs, err := c.GetAllVPCs()
if err != nil {
return nil, fmt.Errorf("failed to list vpcs: %w", err) // preserve chain; callers can errors.Is/As the godo error
} Defensive patterns
Strategy: try-catch
Validate before calling
// preflight: token must be set and callable
if os.Getenv("DIGITALOCEAN_ACCESS_TOKEN") == "" && doToken == "" {
return fmt.Errorf("DigitalOcean access token is not configured")
}
// optionally: doctl auth check / GET /v2/vpcs?per_page=1 to confirm API reachability Type guard
func isDOAPIError(err error) (code int, ok bool) {
var goe *godo.ErrorResponse
if errors.As(err, &goe) {
return goe.Response.StatusCode, true
}
return 0, false
} Try / catch
_, err := c.GetAllVPCs()
if err != nil {
var goe *godo.ErrorResponse
switch {
case errors.As(err, &goe) && goe.Response.StatusCode == http.StatusUnauthorized:
// refresh DO token
case errors.As(err, &goe) && goe.Response.StatusCode == http.StatusTooManyRequests:
// back off and retry after rate-limit reset
default:
// transient: retry with backoff
}
return fmt.Errorf("failed to list vpcs: %w", err)
} Prevention
- Set and periodically rotate a valid DigitalOcean API token with read scope
- Check api.status.digitalocean.com before bulk cluster operations
- Configure proxy/firewall to allow HTTPS to api.digitalocean.com
- Add retry-with-backoff around DO API list calls for 429/5xx
When it happens
Trigger: c.GetAllVPCs() returns an error: invalid/expired DigitalOcean API token, network failure or timeout talking to api.digitalocean.com, DO API 5xx outage, or rate limiting (429) during kops cluster listing/deletion.
Common situations: Running 'kops delete cluster' or 'kops get' against a DigitalOcean cluster with a revoked DO_TOKEN, a misconfigured credentials file, corporate proxy blocking the API, or transient DO API incidents.
Related errors
- failed to retrieve droplet %d: %w
- LoadBalancers.List returned error: %v
- failed to find network %q: %w
- failed to get info for Akamai (Linode) instance %q: %w
- DIGITALOCEAN_ACCESS_TOKEN is required
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/daaa4fe11a5c6762.
Report an issue: GitHub.