{"record":{"id":"c9f7c9f304934f80","repo":"kubernetes/kops","slug":"error-deleting-iam-role-policy-q-v","errorCode":null,"errorMessage":"error deleting IAM role policy %q: %v","messagePattern":"error deleting IAM role policy %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":210,"sourceCode":"\t\t\t\t\t\tklog.V(2).Infof(\"Got NoSuchEntity describing IAM RolePolicy; will treat as already-deleted\")\n\t\t\t\t\t\treturn nil\n\t\t\t\t\t}\n\t\t\t\t\treturn fmt.Errorf(\"error listing IAM role policies for %v\", err)\n\t\t\t\t}\n\t\t\t\tattachedPolicies = append(attachedPolicies, page.AttachedPolicies...)\n\t\t\t}\n\t\t}\n\n\t\t// Delete inline policies\n\t\tfor _, policyName := range policyNames {\n\t\t\tklog.V(2).Infof(\"Deleting IAM role policy %q\", policyName)\n\t\t\trequest := &iam.DeleteRolePolicyInput{\n\t\t\t\tRoleName:   a.Name,\n\t\t\t\tPolicyName: aws.String(policyName),\n\t\t\t}\n\t\t\t_, err := t.Cloud.IAM().DeleteRolePolicy(ctx, request)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error deleting IAM role policy %q: %v\", policyName, err)\n\t\t\t}\n\t\t}\n\n\t\t// Detach Managed Policies\n\t\tfor _, policy := range attachedPolicies {\n\t\t\tklog.V(2).Infof(\"Detaching IAM role policy %v\", policy)\n\t\t\trequest := &iam.DetachRolePolicyInput{\n\t\t\t\tRoleName:  a.Name,\n\t\t\t\tPolicyArn: policy.PolicyArn,\n\t\t\t}\n\t\t\t_, err := t.Cloud.IAM().DetachRolePolicy(ctx, request)\n\t\t\tif err != nil {\n\t\t\t\treturn fmt.Errorf(\"error detaching IAM role policy %q: %v\", *policy.PolicyArn, err)\n\t\t\t}\n\t\t}\n\n\t\trequest := &iam.DeleteRoleInput{\n\t\t\tRoleName: a.Name,","sourceCodeStart":192,"sourceCodeEnd":228,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L192-L228","documentation":"When removing inline policies that should no longer exist, RenderAWS calls DeleteRolePolicy per policy name. Failures are wrapped with the specific policy name, pinpointing which inline policy could not be deleted.","triggerScenarios":"iam.DeleteRolePolicy returns NoSuchEntity (race where policy vanished), AccessDenied, DeleteConflict (policy in use/last cannot delete), or throttling.","commonSituations":"kOps controller lacks iam:DeleteRolePolicy; concurrent reconciliation deletes the policy first (NoSuchEntity race); service-linked or conflicting state on the role; long update runs hitting rate limits.","solutions":["Re-run reconciliation; a NoSuchEntity race resolves itself on the next pass","Grant iam:DeleteRolePolicy (and iam:ListRolePolicies) to the reconciling principal","Back off and retry if throttling; delete policies in smaller batches","Check for DeleteConflict: ensure no dependent sessions/services block the policy removal"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// re-check the policy still exists right before deleting\n_, err := iamClient.GetRolePolicy(ctx, &iam.GetRolePolicyInput{RoleName: roleName, PolicyName: &policyName})\nif err != nil { /* policy already gone; skip delete */ }","typeGuard":null,"tryCatchPattern":"_, err := t.Cloud.IAM().DeleteRolePolicy(ctx, request)\nif err != nil {\n    if awsup.IsIAMNoSuchEntityException(err) {\n        klog.V(2).Infof(\"policy %q already deleted; continuing\", policyName)\n    } else {\n        return fmt.Errorf(\"error deleting IAM role policy %q: %w\", policyName, err)\n    }\n}","preventionTips":["Treat NoSuchEntity on delete as success (idempotent reconcile)","Grant iam:DeleteRolePolicy to the reconciling principal","Serialize delete/detach flows to avoid races with other reconcilers","Retry transient/throttling errors with backoff before failing the run"],"tags":["aws","iam","delete","race","api-error"],"backgroundTag":"aws-iam-api-error","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T12:17:11.808Z"}