kubernetes/kops · error

error updating IAMRole: %v

Error message

error updating IAMRole: %v

What it means

When the trust (assume-role) policy changed, RenderAWS calls IAM UpdateAssumeRolePolicy with the newly rendered document. Any AWS error is wrapped as 'error updating IAMRole: %v' (same message text as the permissions-boundary update paths, so read the inner AWS error to disambiguate).

Source

Thrown at upup/pkg/fi/cloudup/awstasks/iamrole.go:287

				if err != nil {
					return fmt.Errorf("error reading actual policy document: %v", err)
				}
			}

			if actualPolicy == policy {
				klog.Warning("Policies were actually the same")
			} else {
				d := diff.FormatDiff(actualPolicy, policy)
				klog.V(2).Infof("diff: %s", d)
			}

			request := &iam.UpdateAssumeRolePolicyInput{}
			request.PolicyDocument = aws.String(policy)
			request.RoleName = e.Name

			_, err = t.Cloud.IAM().UpdateAssumeRolePolicy(ctx, request)
			if err != nil {
				return fmt.Errorf("error updating IAMRole: %v", err)
			}
		}
		if changes.PermissionsBoundary != nil {
			klog.V(2).Infof("Updating IAMRole PermissionsBoundary %q", *e.Name)

			request := &iam.PutRolePermissionsBoundaryInput{}
			request.RoleName = e.Name
			request.PermissionsBoundary = e.PermissionsBoundary

			if _, err := t.Cloud.IAM().PutRolePermissionsBoundary(ctx, request); err != nil {
				return fmt.Errorf("error updating IAMRole: %v", err)
			}
		} else if a.PermissionsBoundary != nil && e.PermissionsBoundary == nil {
			request := &iam.DeleteRolePermissionsBoundaryInput{}
			request.RoleName = e.Name

			if _, err := t.Cloud.IAM().DeleteRolePermissionsBoundary(ctx, request); err != nil {
				return fmt.Errorf("error updating IAMRole: %v", err)

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Run with klog V=2 to see the rendered policy, then validate it against the IAM policy grammar
  2. Check the inner error for MalformedPolicyDocument and fix Version ("2012-10-17"), Effect, Principal, Action fields
  3. For NoSuchEntity, re-run apply so kOps recreates the role first
  4. Grant iam:UpdateAssumeRolePolicy to the credentials and retry after transient throttling

Example fix

// before: missing/old version and bad principal shape
{"Statement":[{"Effect":"Allow","Principal":"ec2.amazonaws.com","Action":"sts:AssumeRole"}]}

// after
{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ec2.amazonaws.com"},"Action":"sts:AssumeRole"}]}
Defensive patterns

Strategy: validation

Validate before calling

var doc struct {
    Version   string `json:"Version"`
    Statement []struct {
        Effect    string      `json:"Effect"`
        Principal interface{} `json:"Principal"`
        Action    interface{} `json:"Action"`
    } `json:"Statement"`
}
if err := json.Unmarshal([]byte(trustPolicyJSON), &doc); err != nil { return err }
if doc.Version != "2012-10-17" { return fmt.Errorf("unsupported policy Version %q", doc.Version) }

Try / catch

_, err := t.Cloud.IAM().UpdateAssumeRolePolicy(ctx, request)
if err != nil {
    var mpd *iam.MalformedPolicyDocumentException
    if errors.As(err, &mpd) { /* log full policy, fix grammar */ }
    if strings.Contains(err.Error(), "RequestLimitExceeded") { /* backoff + retry */ }
    return err
}

Prevention

When it happens

Trigger: UpdateAssumeRolePolicy returns MalformedPolicyDocument (invalid JSON, wrong Principal/Action shapes, unsupported version), NoSuchEntity (role deleted concurrently), AccessDenied (missing iam:UpdateAssumeRolePolicy), or throttling.

Common situations: Hand-edited trust policy in the cluster spec with a typo; adding a condition or service principal AWS rejects (e.g. wrong format for ec2.amazonaws.com); IAM propagation immediately after role creation; SCPs restricting iam:Update* in restricted accounts.

Related errors


AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05). Data as JSON: /api/errors/6ebd15a86b51d006. Report an issue: GitHub.