{"record":{"id":"7d80bda119ffe27f","repo":"kubernetes/kops","slug":"created-serviceaccount-did-not-have-expected-email","errorCode":null,"errorMessage":"created ServiceAccount did not have expected email; got %q; want %q","messagePattern":"created ServiceAccount did not have expected email; got %q; want %q","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/serviceaccount.go","lineNumber":139,"sourceCode":"\tfqn := \"projects/\" + projectID + \"/serviceAccounts/\" + email\n\n\tif a == nil {\n\t\tklog.V(2).Infof(\"Creating ServiceAccount %q\", fqn)\n\n\t\tsa := &iam.CreateServiceAccountRequest{\n\t\t\tAccountId: accountID,\n\t\t\tServiceAccount: &iam.ServiceAccount{\n\t\t\t\tDescription: fi.ValueOf(e.Description),\n\t\t\t\tDisplayName: fi.ValueOf(e.DisplayName),\n\t\t\t},\n\t\t}\n\n\t\tcreated, err := cloud.IAM().ServiceAccounts().Create(ctx, \"projects/\"+projectID, sa)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error creating ServiceAccount %q: %w\", fqn, err)\n\t\t}\n\t\tif created.Email != email {\n\t\t\treturn fmt.Errorf(\"created ServiceAccount did not have expected email; got %q; want %q\", created.Email, email)\n\t\t}\n\t} else {\n\t\tif changes.Description != nil || changes.DisplayName != nil {\n\t\t\tsa := &iam.ServiceAccount{\n\t\t\t\tEmail:       email,\n\t\t\t\tDescription: fi.ValueOf(e.Description),\n\t\t\t\tDisplayName: fi.ValueOf(e.DisplayName),\n\t\t\t}\n\n\t\t\t_, err := cloud.IAM().ServiceAccounts().Update(ctx, fqn, sa)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error creating ServiceAccount %q: %w\", fqn, err)\n\t\t\t}\n\n\t\t\tchanges.Description = nil\n\t\t\tchanges.DisplayName = nil\n\t\t}\n","sourceCodeStart":121,"sourceCodeEnd":157,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/serviceaccount.go#L121-L157","documentation":"Immediately after creating a service account, RenderGCE verifies that GCP returned the exact email kOps requested. GCP computes the email from the accountId plus project, so a mismatch indicates the API created something unexpected (or a client/API quirk). This is a defensive consistency check, not a common runtime condition.","triggerScenarios":"created.Email != email after a successful Iam.ServiceAccounts().Create call in RenderGCE — e.g. GCP normalized the account ID differently or a proxy/mocks returned an inconsistent response.","commonSituations":"Case differences or unusual characters in the configured email that GCP normalized; stale/faulty API emulator or proxy; upstream google.golang.org/api behavior change; essentially only seen with a mistyped email containing mixed case.","solutions":["Compare got/want emails in the message and correct the Email field in the cluster spec to the exact canonical form (all lowercase).","Verify with `gcloud iam service-accounts describe <created-email>` which account was actually created and update or delete it.","Upgrade kOps and google.golang.org/api to current versions in case of a client-side email handling bug.","If reproducible against a proxy/emulator, run against the real GCP endpoint."],"exampleFix":"// before (mixed case)\nEmail: fi.String(\"Dev-Robot@example-project.iam.gserviceaccount.com\")\n// after\nEmail: fi.String(\"dev-robot@example-project.iam.gserviceaccount.com\")","handlingStrategy":"validation","validationCode":"email := fi.ValueOf(e.Email)\nif email != strings.ToLower(email) {\n    return fmt.Errorf(\"service account email %q must be lowercase\", email)\n}","typeGuard":"func canonicalEmail(email string) bool {\n    return email == strings.ToLower(email) && strings.HasSuffix(email, \".iam.gserviceaccount.com\")\n}","tryCatchPattern":"if err := kopsUpdate(); err != nil {\n    if strings.Contains(err.Error(), \"did not have expected email\") {\n        log.Print(\"delete the unexpected account and fix the Email field to canonical lowercase form\")\n    }\n    return err\n}","preventionTips":["Always store service account emails fully lowercase in cluster specs.","After creation, verify with `gcloud iam service-accounts describe` that the email matches the spec.","Don't run kOps through API-modifying proxies/emulators.","Keep kOps and google.golang.org/api up to date."],"tags":["gce","gcp","iam","service-account","consistency-check"],"backgroundTag":"gcp-resource-email-mismatch","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"}