{"record":{"id":"06671b1b133dd05a","repo":"kubernetes/kops","slug":"error-listing-serviceaccounts-w","errorCode":null,"errorMessage":"error listing ServiceAccounts %w","messagePattern":"error listing ServiceAccounts %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/gce/gce.go","lineNumber":1018,"sourceCode":"\top, err := c.Compute().Routers().Delete(u.Project, u.Region, u.Name)\n\tif err != nil {\n\t\tif gce.IsNotFound(err) {\n\t\t\tklog.Infof(\"Router not found, assuming deleted: %q\", o.SelfLink)\n\t\t\treturn nil\n\t\t}\n\t\treturn fmt.Errorf(\"error deleting router %s: %v\", o.SelfLink, err)\n\t}\n\n\treturn c.WaitForOp(op)\n}\n\nfunc (d *clusterDiscoveryGCE) listServiceAccounts() ([]*resources.Resource, error) {\n\tc := d.gceCloud\n\tctx := context.Background()\n\n\tsas, err := c.IAM().ServiceAccounts().List(ctx, fmt.Sprintf(\"projects/%s\", c.Project()))\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"error listing ServiceAccounts %w\", err)\n\t}\n\tvar resourceTrackers []*resources.Resource\n\tfor _, sa := range sas {\n\t\ttokens := strings.Split(gce.LastComponent(sa.Name), \"@\")\n\t\tif len(tokens) != 2 {\n\t\t\treturn nil, fmt.Errorf(\"Invalid service account email '%s'\", gce.LastComponent(sa.Name))\n\t\t}\n\t\taccountID := tokens[0]\n\t\tnames := []string{gce.ControlPlane, gce.Bastion, gce.Node}\n\t\tfor _, name := range names {\n\t\t\tgeneratedName := gce.ServiceAccountName(name, d.clusterName)\n\t\t\tif generatedName == accountID {\n\t\t\t\tresourceTracker := &resources.Resource{\n\t\t\t\t\tName:    gce.LastComponent(sa.Name),\n\t\t\t\t\tID:      sa.Name,\n\t\t\t\t\tType:    typeServiceAccount,\n\t\t\t\t\tDeleter: deleteServiceAccount,\n\t\t\t\t\tObj:     sa,","sourceCodeStart":1000,"sourceCodeEnd":1036,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/gce/gce.go#L1000-L1036","documentation":"Thrown by listServiceAccounts when the IAM ServiceAccounts().List call for projects/<project> fails. kops enumerates project service accounts to find and clean up the cluster-generated control-plane/bastion/node service accounts.","triggerScenarios":"IAM().ServiceAccounts().List returns an error: 403 (caller lacks iam.serviceAccounts.list, e.g. missing roles/iam.serviceAccountViewer or Service Account Token Creator), invalid project ID in the cluster spec, IAM API disabled, or transient API failure.","commonSituations":"kops runs with a credentials set that has compute rights but not IAM service-account visibility; project ID mismatch between cluster spec and credentials; iam.googleapis.com disabled in the project.","solutions":["Enable the IAM API: gcloud services enable iam.googleapis.com.","Grant roles/iam.serviceAccountViewer (or iam.serviceAccounts.list) to the kops credentials.","Verify the project in the cluster spec matches the credentials' project (`gcloud config get-value project`).","Retry on transient errors (429/5xx)."],"exampleFix":"// before\nreturn nil, fmt.Errorf(\"error listing ServiceAccounts %w\", err)\n// after (distinguish permission errors for a clearer message)\nif apiErr, ok := err.(*googleapi.Error); ok && apiErr.Code == 403 {\n\treturn nil, fmt.Errorf(\"error listing ServiceAccounts in project %s (need roles/iam.serviceAccountViewer): %w\", c.Project(), err)\n}\nreturn nil, fmt.Errorf(\"error listing ServiceAccounts: %w\", err)","handlingStrategy":"validation","validationCode":"// preflight IAM visibility with gcloud-equivalent check\n_, err := iamClient.Projects.ServiceAccounts.List(\"projects/\" + project).Do()\nif err != nil {\n\treturn fmt.Errorf(\"cannot list service accounts in %s; grant roles/iam.serviceAccountViewer: %w\", project, err)\n}","typeGuard":"func isIAMPermissionError(err error) bool {\n\tge, ok := err.(*googleapi.Error)\n\treturn ok && ge.Code == 403\n}","tryCatchPattern":"sas, err := c.IAM().ServiceAccounts().List(ctx, \"projects/\"+c.Project())\nif err != nil {\n\tif isIAMPermissionError(err) {\n\t\tklog.Warningf(\"cannot list service accounts (IAM permission); skipping SA cleanup\")\n\t\treturn nil, nil\n\t}\n\treturn nil, fmt.Errorf(\"error listing ServiceAccounts: %w\", err)\n}","preventionTips":["Enable iam.googleapis.com in the target project.","Grant roles/iam.serviceAccountViewer to the kops credentials.","Keep cluster-spec project identical to the credentials' project."],"tags":["gce","iam","service-account","listing"],"backgroundTag":"gcp-iam-permission-denied","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}