kubernetes/kops · error
error listing Routes: %w
Error message
error listing Routes: %w
What it means
Wraps a failure from Compute Routes().List in listRoutes, which enumerates all routes in the project and filters by cluster-name-with-UUID to find routes owned by the cluster. Any List API failure (this is a full-project listing, so it needs broad compute.routes.list permission) aborts discovery with this wrapped error.
Source
Thrown at pkg/resources/gce/gce.go:748
c := d.gceCloud
var resourceTrackers []*resources.Resource
instancesToDelete := make(map[string]*resources.Resource)
migsToDelete := make(map[string]*resources.Resource)
for _, resource := range resourceMap {
switch resource.Type {
case typeInstance:
instancesToDelete[resource.ID] = resource
case typeInstanceGroupManager:
migsToDelete[resource.ID] = resource
}
}
// TODO: Push-down prefix?
routes, err := c.Compute().Routes().List(ctx, c.Project())
if err != nil {
return nil, fmt.Errorf("error listing Routes: %w", err)
}
for _, r := range routes {
if !d.matchesClusterNameWithUUID(r.Name, maxGCERouteNameLength) {
continue
}
remove := false
for _, w := range r.Warnings {
switch w.Code {
case "NEXT_HOP_INSTANCE_NOT_FOUND":
remove = true
case "NEXT_HOP_NOT_RUNNING":
// It might not be running, but it probably exists.
remove = false
default:
klog.Infof("Unknown warning on route %q: %q", r.Name, w.Code)
}
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Grant compute.routes.list (roles/compute.networkViewer or compute.networkAdmin) to the credentials, including on shared VPC host projects.
- Retry with backoff if the wrapped error is 429/5xx.
- Reduce route-table pressure: clean up stale routes in the project if listing times out.
- Verify the correct project is configured (cluster in a service project but routes in the host project).
- Inspect the wrapped error with errors.As for the precise Google API status.
Defensive patterns
Strategy: retry
Validate before calling
// pre-check list permission cheaply
_, err := computeService.Routes.List(project).PageSize(1).Do()
if err != nil {
if gerr, ok := err.(*googleapi.Error); ok && gerr.Code == 403 {
return fmt.Errorf("service account lacks compute.routes.list on %s", project)
}
} Type guard
func isGCEAPIError(err error) (*googleapi.Error, bool) {
var gerr *googleapi.Error
return gerr, errors.As(err, &gerr)
} Try / catch
routes, err := listRoutes(ctx, c)
if err != nil {
var gerr *googleapi.Error
if errors.As(err, &gerr) && (gerr.Code == 429 || gerr.Code >= 500) {
time.Sleep(backoff); routes, err = listRoutes(ctx, c) // retry once
}
if err != nil { return err }
} Prevention
- Grant roles/compute.networkViewer so routes.list works, including on shared VPC host projects
- Use a context with a generous timeout for large route tables
- Prune stale routes from the project periodically
- Retry 429/5xx with backoff — List calls are quota-sensitive
- Verify the project ID in credentials matches the cluster's project
When it happens
Trigger: c.Compute().Routes().List(ctx, project) fails with 403 permission denied (routes.list not granted), 429 rate limit on list calls, 5xx, or network/timeout failure for large route tables; also service-account impersonation lacking the right scopes.
Common situations: Shared VPC host project where kops credentials have no routes.list on that project; projects with thousands of routes hitting timeouts/quota; credential rotation removing compute.networkViewer; GCP API outage during kops delete cluster.
Related errors
- error listing Addresses: %v
- error listing subnetworks: %v
- error getting ForwardingRule %q: %w
- error getting TargetPool %q: %w
- error deleting Route %s: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/5c29894f1ec34342.
Report an issue: GitHub.