kubernetes/kops · error

error deleting IAM role: %v

Error message

error deleting IAM role: %v

What it means

In IAMRole.RenderAWS, after detaching policies, kOps calls IAM DeleteRole to remove the role. Any error from the AWS API is wrapped as 'error deleting IAM role: %v', aborting the deletion of that task. The wrapped error carries the raw AWS SDK message.

Source

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

		// Detach Managed Policies
		for _, policy := range attachedPolicies {
			klog.V(2).Infof("Detaching IAM role policy %v", policy)
			request := &iam.DetachRolePolicyInput{
				RoleName:  a.Name,
				PolicyArn: policy.PolicyArn,
			}
			_, err := t.Cloud.IAM().DetachRolePolicy(ctx, request)
			if err != nil {
				return fmt.Errorf("error detaching IAM role policy %q: %v", *policy.PolicyArn, err)
			}
		}

		request := &iam.DeleteRoleInput{
			RoleName: a.Name,
		}
		if _, err := t.Cloud.IAM().DeleteRole(ctx, request); err != nil {
			return fmt.Errorf("error deleting IAM role: %v", err)
		}
		return nil
	}

	policy, err := fi.ResourceAsString(e.RolePolicyDocument)
	if err != nil {
		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 {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Inspect the wrapped AWS error: for DeleteConflict remove remaining instance-profile/policy associations and retry
  2. For NoSuchEntity, re-run kops delete cluster so the task state refreshes and the role is marked gone
  3. Add iam:DeleteRole and iam:ListInstanceProfilesForRole to the credentials' policy
  4. Retry later with backoff if the error indicates throttling (RequestLimitExceeded)

Example fix

// before
_, err := t.Cloud.IAM().DeleteRole(ctx, request)

// after: tolerate already-deleted roles
if _, err := t.Cloud.IAM().DeleteRole(ctx, request); err != nil {
    var nfe *iam.NoSuchEntityException
    if !errors.As(err, &nfe) {
        return fmt.Errorf("error deleting IAM role: %v", err)
    }
}
Defensive patterns

Strategy: try-catch

Validate before calling

attached, _ := iamClient.ListAttachedRolePolicies(&iam.ListAttachedRolePoliciesInput{RoleName: &roleName})
profiles, _ := iamClient.ListInstanceProfilesForRole(&iam.ListInstanceProfilesForRoleInput{RoleName: &roleName})
if len(attached.AttachedPolicies) > 0 || len(profiles.InstanceProfiles) > 0 {
    return fmt.Errorf("role %s is not deletable yet", roleName)
}

Try / catch

_, err := t.Cloud.IAM().DeleteRole(ctx, req)
if err != nil {
    var nfe *iam.NoSuchEntityException
    if errors.As(err, &nfe) { return nil } // already gone
    if strings.Contains(err.Error(), "DeleteConflict") { /* clean associations, retry */ }
    return err
}

Prevention

When it happens

Trigger: DeleteRole returns NoSuchEntity (role vanished concurrently), DeleteConflict (role still bound to an instance profile, or policies remain attached), AccessDenied (missing iam:DeleteRole), or throttling during bulk cluster deletion.

Common situations: Tearing down a cluster where an autoscaling group or node still references the role; external controllers recreated attached policies between detach and delete; IAM rate limiting when deleting dozens of roles at once; credentials scoped too narrowly.

Related errors


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