{"record":{"id":"77d39119d873d8e1","repo":"kubernetes/kops","slug":"error-tagging-iamrole-v","errorCode":null,"errorMessage":"error tagging IAMRole: %v","messagePattern":"error tagging IAMRole: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":330,"sourceCode":"\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 {\n\tName                *string                  `cty:\"name\"`\n\tAssumeRolePolicy    *terraformWriter.Literal `cty:\"assume_role_policy\"`\n\tPermissionsBoundary *string                  `cty:\"permissions_boundary\"`\n\tTags                map[string]string        `cty:\"tags\"`\n}\n\nfunc (_ *IAMRole) RenderTerraform(t *terraform.TerraformTarget, a, e, changes *IAMRole) error {\n\tpolicy, err := t.AddFileResource(\"aws_iam_role\", *e.Name, \"policy\", e.RolePolicyDocument, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error rendering RolePolicyDocument: %v\", err)","sourceCodeStart":312,"sourceCodeEnd":348,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L312-L348","documentation":"After untagging stale keys, RenderAWS applies the desired tags via IAM TagRole with mapToIAMTags(e.Tags). Errors are wrapped as 'error tagging IAMRole: %v', the last step of the tag reconciliation branch.","triggerScenarios":"TagRole returns InvalidInput (invalid tag key/value format, reserved aws: prefix without permission), LimitExceeded (more than 50 tags on the role), NoSuchEntity (role gone), AccessDenied (missing iam:TagRole), or throttling during bulk updates.","commonSituations":"Very large cluster spec tag maps exceeding the 50-tag IAM quota; tags auto-added by other tooling pushing the role over quota; invalid characters in user-supplied tag values (e.g. newlines); region-wide IAM rate limits during cluster creation.","solutions":["Keep total role tags at 50 or fewer — trim the cluster spec tag map","Validate key/value charset and lengths (key max 128, value max 256) before applying","For LimitExceeded caused by external tags, remove unused tags with aws iam untag-role first","Add iam:TagRole to the credentials and back off/retry on RequestLimitExceeded"],"exampleFix":"// before: 60 tags in spec -> LimitExceeded\n\"tags\": {\"t01\":\"v\", \"...\": \"...\", \"t60\":\"v\"}\n\n// after: consolidated under quota\n\"tags\": {\"ManagedBy\":\"kops\", \"Cluster\":\"prod-eu\", \"Team\":\"platform\"}","handlingStrategy":"validation","validationCode":"if len(desiredTags) > 50 { return fmt.Errorf(\"IAM allows at most 50 tags; got %d\", len(desiredTags)) }\nfor k, v := range desiredTags {\n    if len(k) > 128 || len(v) > 256 { return fmt.Errorf(\"tag %q over IAM length limit\", k) }\n}\nexisting, _ := iamClient.ListRoleTags(&iam.ListRoleTagsInput{RoleName: &roleName})\nif len(existing.Tags)+len(desiredTags) > 50 { return fmt.Errorf(\"role would exceed 50-tag quota\") }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Consolidate cluster tags; count existing external tags before adding more","Sanitize tag keys/values (charset, lengths) at spec-authoring time in CI","Strip stale tags via untag first when approaching the 50-tag quota","Back off on RequestLimitExceeded when creating many roles at once"],"tags":["aws","iam","go","tags"],"backgroundTag":"aws-tag-limit-exceeded","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"}