{"record":{"id":"2851e7d148a935fe","repo":"kubernetes/kops","slug":"invalid-service-account-email-s","errorCode":null,"errorMessage":"Invalid service account email '%s'","messagePattern":"Invalid service account email '(.+?)'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/resources/gce/gce.go","lineNumber":1024,"sourceCode":"\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,\n\t\t\t\t}\n\n\t\t\t\tklog.V(4).Infof(\"found resource: %s\", sa.Name)\n\t\t\t\tresourceTrackers = append(resourceTrackers, resourceTracker)\n\t\t\t\tbreak\n\t\t\t}","sourceCodeStart":1006,"sourceCodeEnd":1042,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/resources/gce/gce.go#L1006-L1042","documentation":"Thrown by listServiceAccounts when a service account resource name cannot be split into exactly two '@'-separated parts. kops derives the account ID (local part of the email) from the SA resource name via LastComponent and expects an email form like name@project.iam.gserviceaccount.com; a malformed name breaks this assumption.","triggerScenarios":"A service account exists in the project whose resource name's last component contains zero or multiple '@' characters — e.g. programmatically created SAs with unusual emails, SAs created by other tooling with unexpected naming, or a change in IAM API resource-name format.","commonSituations":"Project contains service accounts created by Terraform/other automation with custom emails; default App Engine or compute SAs with edge-case names; future API format drift.","solutions":["List project SAs (`gcloud iam service-accounts list`) and inspect the malformed email; recreate or remove the offending SA.","Treat non-matching SAs as skippable instead of aborting the whole cleanup, since only cluster-generated names (control-plane/bastion/node) matter.","If it blocks cluster deletion, temporarily delete/rename the malformed SA so discovery completes."],"exampleFix":"// before\nif len(tokens) != 2 {\n\treturn nil, fmt.Errorf(\"Invalid service account email '%s'\", gce.LastComponent(sa.Name))\n}\n// after (skip non-cluster SAs instead of failing the whole listing)\nif len(tokens) != 2 {\n\tklog.V(4).Infof(\"skipping service account with unexpected name %q\", gce.LastComponent(sa.Name))\n\tcontinue\n}","handlingStrategy":"validation","validationCode":"email := gce.LastComponent(sa.Name)\nif strings.Count(email, \"@\") != 1 {\n\t// skip or sanitize before processing\n\tklog.V(4).Infof(\"skipping malformed SA name %q\", email)\n}","typeGuard":"func isServiceAccountEmail(name string) bool {\n\tparts := strings.Split(name, \"@\")\n\treturn len(parts) == 2 && parts[0] != \"\" && strings.HasSuffix(parts[1], \".iam.gserviceaccount.com\")\n}","tryCatchPattern":"// error only occurs mid-loop; wrap the SA processing loop\nfor _, sa := range sas {\n\tif err := processServiceAccount(sa); err != nil {\n\t\tklog.Warningf(\"skipping service account %q: %v\", sa.Name, err)\n\t\tcontinue\n\t}\n}","preventionTips":["Audit project SAs for unusual emails created by other tooling.","Only attempt to match cluster-generated SA names; skip others.","Pin/verify the cloud library version that returns SA resource names."],"tags":["gce","iam","service-account","validation"],"backgroundTag":"service-account-email-parse-failed","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"}