kubernetes/kops · error
error creating IAMRole: %v
Error message
error creating IAMRole: %v
What it means
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.
Source
Thrown at upup/pkg/fi/cloudup/awstasks/iamrole.go:256
return fmt.Errorf("error rendering RolePolicyDocument: %v", err)
}
if a == nil {
klog.V(2).Infof("Creating IAMRole with Name:%q", *e.Name)
request := &iam.CreateRoleInput{}
request.AssumeRolePolicyDocument = aws.String(policy)
request.RoleName = e.Name
request.Tags = mapToIAMTags(e.Tags)
if e.PermissionsBoundary != nil {
request.PermissionsBoundary = e.PermissionsBoundary
}
response, err := t.Cloud.IAM().CreateRole(ctx, request)
if err != nil {
klog.V(2).Infof("IAMRole policy: %s", policy)
return fmt.Errorf("error creating IAMRole: %v", err)
}
e.ID = response.Role.RoleId
} else {
if changes.RolePolicyDocument != nil {
klog.V(2).Infof("Updating IAMRole AssumeRolePolicy %q", *e.Name)
var err error
actualPolicy := ""
if a.RolePolicyDocument != nil {
actualPolicy, err = fi.ResourceAsString(a.RolePolicyDocument)
if err != nil {
return fmt.Errorf("error reading actual policy document: %v", err)
}
}
if actualPolicy == policy {View on GitHub (pinned to 4c8573c808)
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
Example fix
// before: malformed trust principal
"Principal": {"AWS": "arn:aws:iam::123456789012:root/*"}
// after: valid principal
"Principal": {"AWS": "arn:aws:iam::123456789012:root"} Defensive patterns
Strategy: try-catch
Validate before calling
// validate trust policy + name availability before create
var doc map[string]interface{}
if err := json.Unmarshal([]byte(trustPolicyJSON), &doc); err != nil { return err }
_, err := iamClient.GetRole(&iam.GetRoleInput{RoleName: aws.String(roleName)})
if err == nil { return fmt.Errorf("role %s already exists; import or delete it first", roleName) } Try / catch
_, err := t.Cloud.IAM().CreateRole(ctx, request)
if err != nil {
var aee *iam.EntityAlreadyExistsException
if errors.As(err, &aee) { /* adopt or delete existing role */ }
klog.V(2).Infof("IAMRole policy: %s", policy) // inspect rejected document
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error detaching IAM role policy %q: %v
- error deleting IAM role: %v
- failed to generate AWS IAM Policy: %v
- failed to generate AWS IAM S3 access statements: %v
- unknown writeable path, can't apply IAM policy: %q
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/6e96350c554095a4.
Report an issue: GitHub.