{"record":{"id":"f3d5d46c3798b63f","repo":"kubernetes/kops","slug":"error-creating-iam-policy-for-bucket-gs-s-w","errorCode":null,"errorMessage":"error creating IAM policy for bucket gs://%s: %w","messagePattern":"error creating IAM policy for bucket gs://(.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/gcetasks/storagebucketiam.go","lineNumber":115,"sourceCode":"\t}\n\tif fi.ValueOf(e.Role) == \"\" {\n\t\treturn fi.RequiredField(\"Role\")\n\t}\n\treturn nil\n}\n\nfunc (_ *StorageBucketIAM) RenderGCE(t *gce.GCEAPITarget, a, e, changes *StorageBucketIAM) error {\n\tctx := context.TODO()\n\n\tbucket := fi.ValueOf(e.Bucket)\n\tmember := \"serviceAccount:\" + fi.ValueOf(e.MemberServiceAccount.Email)\n\trole := fi.ValueOf(e.Role)\n\n\tklog.V(2).Infof(\"Creating GCS bucket IAM for gs://%s for %s as %s\", bucket, member, role)\n\n\tpolicy, err := t.Cloud.Storage().Bucket(bucket).IAM().V3().Policy(ctx)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating IAM policy for bucket gs://%s: %w\", bucket, err)\n\t}\n\n\tchanged := patchPolicy(policy, member, role)\n\n\tif !changed {\n\t\tklog.Warningf(\"did not need to change policy (concurrent change?)\")\n\t\treturn nil\n\t}\n\n\tif err := t.Cloud.Storage().Bucket(bucket).IAM().V3().SetPolicy(ctx, policy); err != nil {\n\t\treturn fmt.Errorf(\"error updating GCS bucket IAM for gs://%s: %v\", bucket, err)\n\t}\n\n\treturn nil\n}\n\n// terraformStorageBucketIAM is the model for a terraform google_storage_bucket_iam_member rule\ntype terraformStorageBucketIAM struct {","sourceCodeStart":97,"sourceCodeEnd":133,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/gcetasks/storagebucketiam.go#L97-L133","documentation":"StorageBucketIAM.RenderGCE wraps a failure while reading the bucket's current IAM policy before patching it. The misleading \"creating IAM policy\" wording refers to fetching the policy so the desired member binding can be added; the underlying error is in the wrapped %w.","triggerScenarios":"t.Cloud.Storage().Bucket(bucket).IAM().V3().Policy(ctx) fails during RenderGCE when kOps is about to add the serviceAccount member to the bucket policy.","commonSituations":"Missing storage.buckets.getIamPolicy permission for the bucket; bucket deleted between Find and apply; bucket in another project without cross-project grants; org policy blocking IAM reads via domain-restricted sharing constraints; transient GCP 5xx.","solutions":["Read the wrapped error: 403 => grant roles/storage.admin (or storage.buckets.getIamPolicy) to the kOps service account; 404 => recreate/fix the bucket.","Ensure the bucket task runs before the StorageBucketIAM task so the bucket exists.","Check org policy constraints (iam.allowedPolicyMemberDomains) if member binding is the real blocker.","Retry on transient errors; confirm credentials with `gcloud storage buckets get-iam-policy`."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"if _, err := exec.Command(\"gcloud\", \"storage\", \"buckets\", \"describe\", \"gs://\"+bucket).Output(); err != nil {\n    return fmt.Errorf(\"bucket gs://%s must exist before IAM task: %w\", bucket, err)\n}\nif !hasPerm(\"storage.buckets.getIamPolicy\") { return fmt.Errorf(\"missing storage.buckets.getIamPolicy\") }","typeGuard":null,"tryCatchPattern":"if err := kopsUpdate(); err != nil {\n    if strings.Contains(err.Error(), \"error creating IAM policy for bucket\") {\n        if strings.Contains(err.Error(), \"404\") {\n            log.Print(\"bucket deleted; re-run to recreate bucket first\")\n        } else if isTransient(err) {\n            retryWithBackoff()\n        }\n    }\n    return err\n}","preventionTips":["Ensure task ordering so the bucket exists before the IAM member task.","Grant roles/storage.admin to the kOps identity for full IAM read/write.","Check org policy iam.allowedPolicyMemberDomains if members get rejected.","Avoid concurrent pipelines mutating the same bucket's IAM."],"tags":["gcs","gcp","storage","iam","policy","api-error"],"backgroundTag":"gcs-bucket-api-error","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"}