{"record":{"id":"6e96350c554095a4","repo":"kubernetes/kops","slug":"error-creating-iamrole-v","errorCode":null,"errorMessage":"error creating IAMRole: %v","messagePattern":"error creating IAMRole: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":256,"sourceCode":"\t\treturn fmt.Errorf(\"error rendering RolePolicyDocument: %v\", err)\n\t}\n\n\tif a == nil {\n\t\tklog.V(2).Infof(\"Creating IAMRole with Name:%q\", *e.Name)\n\n\t\trequest := &iam.CreateRoleInput{}\n\t\trequest.AssumeRolePolicyDocument = aws.String(policy)\n\t\trequest.RoleName = e.Name\n\t\trequest.Tags = mapToIAMTags(e.Tags)\n\n\t\tif e.PermissionsBoundary != nil {\n\t\t\trequest.PermissionsBoundary = e.PermissionsBoundary\n\t\t}\n\n\t\tresponse, err := t.Cloud.IAM().CreateRole(ctx, request)\n\t\tif err != nil {\n\t\t\tklog.V(2).Infof(\"IAMRole policy: %s\", policy)\n\t\t\treturn fmt.Errorf(\"error creating IAMRole: %v\", err)\n\t\t}\n\n\t\te.ID = response.Role.RoleId\n\t} else {\n\t\tif changes.RolePolicyDocument != nil {\n\t\t\tklog.V(2).Infof(\"Updating IAMRole AssumeRolePolicy %q\", *e.Name)\n\n\t\t\tvar err error\n\n\t\t\tactualPolicy := \"\"\n\t\t\tif a.RolePolicyDocument != nil {\n\t\t\t\tactualPolicy, err = fi.ResourceAsString(a.RolePolicyDocument)\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn fmt.Errorf(\"error reading actual policy document: %v\", err)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif actualPolicy == policy {","sourceCodeStart":238,"sourceCodeEnd":274,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L238-L274","documentation":"RenderAWS builds a CreateRoleInput (name, assume-role policy document, optional permissions boundary) and calls IAM CreateRole. Any AWS error is logged with the rendered policy at klog V(2) and wrapped as 'error creating IAMRole: %v', so enabling V=2 logging shows the exact document AWS rejected.","triggerScenarios":"CreateRole returns EntityAlreadyExists (name taken by another role in the account), MalformedPolicyDocument (invalid trust policy JSON or wrong principal format), LimitExceeded (role count quota), AccessDenied (missing iam:CreateRole), or InvalidInput for a malformed permissions-boundary ARN.","commonSituations":"Recreating a cluster in an account where a role of the same name persists; trust policy with a wrong ARN/principal shape; org-level service control policies denying iam:CreateRole; account hitting IAM role limits.","solutions":["Check the wrapped AWS code: for EntityAlreadyExists import/adopt or delete the pre-existing role, then retry","Validate the trust policy JSON has a valid Statement with Effect/Principal/Action (klog V=2 prints it)","For LimitExceeded delete unused roles or request an IAM quota increase","Verify credentials have iam:CreateRole and that no SCP denies it"],"exampleFix":"// before: malformed trust principal\n\"Principal\": {\"AWS\": \"arn:aws:iam::123456789012:root/*\"}\n\n// after: valid principal\n\"Principal\": {\"AWS\": \"arn:aws:iam::123456789012:root\"}","handlingStrategy":"try-catch","validationCode":"// validate trust policy + name availability before create\nvar doc map[string]interface{}\nif err := json.Unmarshal([]byte(trustPolicyJSON), &doc); err != nil { return err }\n_, err := iamClient.GetRole(&iam.GetRoleInput{RoleName: aws.String(roleName)})\nif err == nil { return fmt.Errorf(\"role %s already exists; import or delete it first\", roleName) }","typeGuard":null,"tryCatchPattern":"_, err := t.Cloud.IAM().CreateRole(ctx, request)\nif err != nil {\n    var aee *iam.EntityAlreadyExistsException\n    if errors.As(err, &aee) { /* adopt or delete existing role */ }\n    klog.V(2).Infof(\"IAMRole policy: %s\", policy) // inspect rejected document\n    return err\n}","preventionTips":["Run with -v=2 so the rejected policy document is logged on failure","Uniquely name roles per cluster to avoid collisions in shared accounts","Validate trust policy JSON schema (Version/Effect/Principal/Action) in CI","Check account IAM role quota before creating large multi-cluster setups"],"tags":["aws","iam","go","kops"],"backgroundTag":"entity-already-exists","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"}