{"record":{"id":"3f2d834f54827c1c","repo":"kubernetes/kops","slug":"error-untagging-iamrole-v","errorCode":null,"errorMessage":"error untagging IAMRole: %v","messagePattern":"error untagging IAMRole: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":320,"sourceCode":"\t\t\trequest.RoleName = e.Name\n\n\t\t\tif _, err := t.Cloud.IAM().DeleteRolePermissionsBoundary(ctx, request); err != nil {\n\t\t\t\treturn fmt.Errorf(\"error updating IAMRole: %v\", err)\n\t\t\t}\n\t\t}\n\t\tif changes.Tags != nil {\n\t\t\tif len(a.Tags) > 0 {\n\t\t\t\texistingTagKeys := make([]string, 0)\n\t\t\t\tfor k := range a.Tags {\n\t\t\t\t\texistingTagKeys = append(existingTagKeys, k)\n\t\t\t\t}\n\t\t\t\tuntagRequest := &iam.UntagRoleInput{\n\t\t\t\t\tRoleName: e.Name,\n\t\t\t\t\tTagKeys:  existingTagKeys,\n\t\t\t\t}\n\t\t\t\t_, err = t.Cloud.IAM().UntagRole(ctx, untagRequest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error untagging IAMRole: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t\tif len(e.Tags) > 0 {\n\t\t\t\ttagRequest := &iam.TagRoleInput{\n\t\t\t\t\tRoleName: e.Name,\n\t\t\t\t\tTags:     mapToIAMTags(e.Tags),\n\t\t\t\t}\n\t\t\t\t_, err = t.Cloud.IAM().TagRole(ctx, tagRequest)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error tagging IAMRole: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\ntype terraformIAMRole struct {","sourceCodeStart":302,"sourceCodeEnd":338,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L302-L338","documentation":"When tags change, RenderAWS first removes tag keys that exist on the actual role but not in the desired spec via IAM UntagRole. Errors are wrapped as 'error untagging IAMRole: %v'. This only runs inside the changes.Tags branch after computing existingTagKeys.","triggerScenarios":"UntagRole returns NoSuchEntity (role deleted concurrently), InvalidInput (a tag key violates IAM rules — empty, over 128 chars, invalid characters — or too many keys), AccessDenied (missing iam:UntagRole), or RequestLimitExceeded throttling when many roles are updated at once.","commonSituations":"Cluster spec contains tags with characters IAM rejects (e.g. reserved aws: prefix, unsupported unicode); bulk apply across many roles triggering IAM throttling; external automation deleted the role mid-apply.","solutions":["Validate tag keys: 1-128 chars, letters/digits/spaces and _ . : / = + - @ only; fix the cluster spec tags","For RequestLimitExceeded, retry with backoff or reduce parallel applies","Grant iam:UntagRole (and iam:ListRoleTags) to the credentials","For NoSuchEntity, re-run apply to refresh task state"],"exampleFix":"// before: reserved-prefix / overlong key\n\"tags\": {\"aws:legacy:env\": \"x\", \"<128+ char key>\": \"v\"}\n\n// after: compliant keys\n\"tags\": {\"Owner\": \"platform\", \"Cluster\": \"prod-eu\"}","handlingStrategy":"retry","validationCode":"func validIAMTagKey(k string) bool {\n    if len(k) < 1 || len(k) > 128 { return false }\n    re := regexp.MustCompile(`^[\\p{L}\\p{Z}\\p{N}_.:/=+\\-@]+$`)\n    return re.MatchString(k)\n}\nfor k := range tagsToRemove { if !validIAMTagKey(k) { return fmt.Errorf(\"invalid tag key %q\", k) } }","typeGuard":null,"tryCatchPattern":"// backoff on IAM throttling\nfor i := 0; i < 5; i++ {\n    _, err := t.Cloud.IAM().UntagRole(ctx, req)\n    if err == nil { break }\n    if !strings.Contains(err.Error(), \"RequestLimitExceeded\") { return err }\n    time.Sleep(time.Duration(1<<i) * time.Second)\n}","preventionTips":["Run bulk applies sequentially or with jitter to stay under IAM rate limits","Restrict tag keys to the IAM-allowed charset in cluster specs","Add iam:UntagRole and iam:ListRoleTags to automation roles","Re-run apply once after any NoSuchEntity failure to refresh state"],"tags":["aws","iam","go","tags"],"backgroundTag":"aws-api-throttling","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"}