{"record":{"id":"f6a60c870dcfb898","repo":"kubernetes/kops","slug":"error-listing-routers-v","errorCode":null,"errorMessage":"error listing routers: %v","messagePattern":"error listing routers: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/gce/gce.go","lineNumber":966,"sourceCode":"\t\tif gce.IsNotFound(err) {\n\t\t\tklog.Infof(\"Subnetwork not found, assuming deleted: %q\", o.SelfLink)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting Subnetwork %s: %v\", o.SelfLink, err)\n\t}\n\n\treturn c.WaitForOp(op)\n}\n\nfunc (d *clusterDiscoveryGCE) listRouters() ([]*resources.Resource, error) {\n\tc := d.gceCloud\n\n\tvar resourceTrackers []*resources.Resource\n\tctx := context.Background()\n\n\trouters, err := c.Compute().Routers().List(ctx, c.Project(), c.Region())\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing routers: %v\", err)\n\t}\n\n\tfor _, o := range routers {\n\t\tif !d.matchesClusterName(o.Name) {\n\t\t\tklog.V(8).Infof(\"skipping Router with name %q\", o.Name)\n\t\t\tcontinue\n\t\t}\n\n\t\tresourceTracker := &resources.Resource{\n\t\t\tName:    o.Name,\n\t\t\tID:      o.Name,\n\t\t\tType:    typeRouter,\n\t\t\tDeleter: deleteRouter,\n\t\t\tObj:     o,\n\t\t}\n\n\t\tklog.V(4).Infof(\"found resource: %s\", o.SelfLink)\n\t\tresourceTrackers = append(resourceTrackers, resourceTracker)","sourceCodeStart":948,"sourceCodeEnd":984,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/gce/gce.go#L948-L984","documentation":"Thrown by listRouters in pkg/resources/gce/gce.go when the Compute Routers().List call for the project/region fails. This is a read-only enumeration step used to find cluster-owned Cloud Routers during cluster discovery/teardown; the error aborts building the resource tracker list.","triggerScenarios":"Calling Routers().List(ctx, project, region) and receiving any API error: 403 permission denied (missing compute.routers.list), invalid/unknown region name, disabled Compute API, quota exhaustion, or network outage.","commonSituations":"Service account lacking compute viewer roles; kops configured with a region the credentials can't access; Compute Engine API disabled in the project; transient GCE API unavailability during delete cluster.","solutions":["Read the wrapped error for the API status code and message.","Verify Compute Engine API is enabled: gcloud services enable compute.googleapis.com.","Grant the credentials compute.networkViewer / compute.routers.list permission in the target project.","Confirm the region in the cluster spec matches an existing GCE region (e.g. us-central1, not us-central1-a).","Retry if the error is 429/5xx."],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"error listing routers: %v\", err)\n// after (skip non-cluster regions gracefully, preserve cause)\nreturn nil, fmt.Errorf(\"error listing routers in %s/%s: %w\", c.Project(), c.Region(), err)","handlingStrategy":"validation","validationCode":"// preflight: credentials and region validity\nif _, err := netid.ParseRegion(region); err != nil { return err }\n_, err := computeClient.Routers().List(ctx, project, region)\n_ = err // verify list works before mutating anything","typeGuard":"func isPermissionDenied(err error) bool {\n\tge, ok := err.(*googleapi.Error)\n\treturn ok && ge.Code == 403\n}","tryCatchPattern":"routers, err := c.Compute().Routers().List(ctx, project, region)\nif err != nil {\n\tif isPermissionDenied(err) {\n\t\treturn fmt.Errorf(\"needs compute.routers.list on %s: %w\", project, err)\n\t}\n\treturn fmt.Errorf(\"error listing routers: %w\", err)\n}","preventionTips":["Enable compute.googleapis.com in the project first.","Run a preflight `gcloud compute routers list --project=... --regions=...` with the same credentials.","Use region (not zone) values in the cluster spec."],"tags":["gce","router","listing","cloud-api"],"backgroundTag":"gce-api-list-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}