kubernetes/kops · error
ServiceAccount with email %q not found
Error message
ServiceAccount with email %q not found
What it means
RenderGCE throws this when a GCE ServiceAccount task is marked Shared (i.e. kOps does not own or create the service account) but the Find phase returned no existing service account for the configured email. For shared accounts kOps must reuse a pre-existing account; creating it would be wrong, so the apply aborts. It means the cluster spec references a service account that does not exist in the target GCP project.
Source
Thrown at upup/pkg/fi/cloudup/gcetasks/serviceaccount.go:112
return fi.CloudupDefaultDeltaRunMethod(e, c)
}
func (_ *ServiceAccount) CheckChanges(a, e, changes *ServiceAccount) error {
return nil
}
func (_ *ServiceAccount) RenderGCE(t *gce.GCEAPITarget, a, e, changes *ServiceAccount) error {
ctx := context.TODO()
cloud := t.Cloud
email := fi.ValueOf(e.Email)
shared := fi.ValueOf(e.Shared)
if shared {
// Verify the service account was found
if a == nil {
return fmt.Errorf("ServiceAccount with email %q not found", email)
}
}
accountID, projectID, err := gce.SplitServiceAccountEmail(email)
if err != nil {
return err
}
fqn := "projects/" + projectID + "/serviceAccounts/" + email
if a == nil {
klog.V(2).Infof("Creating ServiceAccount %q", fqn)
sa := &iam.CreateServiceAccountRequest{
AccountId: accountID,
ServiceAccount: &iam.ServiceAccount{
Description: fi.ValueOf(e.Description),
DisplayName: fi.ValueOf(e.DisplayName),View on GitHub (pinned to 4c8573c808)
Solutions
- Verify the service account exists: `gcloud iam service-accounts list --project=<project>` and compare with the Email in the cluster spec.
- Fix a typo or wrong project ID in the service account email in the cluster spec, then re-run update.
- Recreate the deleted service account (or change Shared to false so kOps creates and manages it).
- Ensure kOps credentials target the project where the account actually lives (check GOOGLE_APPLICATION_CREDENTIALS / project flag).
Example fix
// cluster spec, before (account doesn't exist in project) sharedServiceAccount: shared@example-project.iam.gserviceaccount.com // after dev-robot@example-project.iam.gserviceaccount.com // correct, existing account
Defensive patterns
Strategy: validation
Validate before calling
sa := fi.ValueOf(e.Email)
if fi.ValueOf(e.Shared) {
if _, err := exec.Command("gcloud", "iam", "service-accounts", "describe", sa, "--format=value(email)").Output(); err != nil {
return fmt.Errorf("shared ServiceAccount %q does not exist in target project", sa)
}
} Type guard
func sharedAccountFound(a *ServiceAccount, shared bool) bool { return !shared || a != nil } Try / catch
if err := kopsUpdate(); err != nil {
if strings.Contains(err.Error(), "ServiceAccount with email") {
log.Printf("shared SA missing; create it with: gcloud iam service-accounts create <id> --project=<proj>")
}
return err
} Prevention
- Pre-create shared service accounts with gcloud/Terraform before `kops update cluster`.
- Copy-paste the exact email from `gcloud iam service-accounts list` to avoid typos.
- Pin the project in the spec and verify kOps authenticates to the same project.
- Add a pre-flight script validating all shared:* resources exist.
When it happens
Trigger: Running `kops update cluster` against GCE where a ServiceAccount task has Shared=true and the email does not resolve to an existing IAM service account (Find returned nil, so `a == nil` in RenderGCE).
Common situations: Typo in the service account email in the cluster spec; the account was deleted in GCP after the cluster was created; cluster pointed at the wrong --project or wrong project inside the email (emails embed project ID via gce.SplitServiceAccountEmail); the account lives in a different project than the one kOps is authenticated against.
Related errors
- error creating ServiceAccount %q: %w
- created ServiceAccount did not have expected email; got %q;
- cannot apply changes to ServiceAccount: %v
- error listing ServiceAccounts %w
- Invalid service account email '%s'
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/ee4ad53318368868.
Report an issue: GitHub.