kubernetes/kops · error

error untagging IAMRole: %v

Error message

error untagging IAMRole: %v

What it means

When tags change, RenderAWS first removes tag keys that exist on the actual role but not in the desired spec via IAM UntagRole. Errors are wrapped as 'error untagging IAMRole: %v'. This only runs inside the changes.Tags branch after computing existingTagKeys.

Source

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

			request.RoleName = e.Name

			if _, err := t.Cloud.IAM().DeleteRolePermissionsBoundary(ctx, request); err != nil {
				return fmt.Errorf("error updating IAMRole: %v", err)
			}
		}
		if changes.Tags != nil {
			if len(a.Tags) > 0 {
				existingTagKeys := make([]string, 0)
				for k := range a.Tags {
					existingTagKeys = append(existingTagKeys, k)
				}
				untagRequest := &iam.UntagRoleInput{
					RoleName: e.Name,
					TagKeys:  existingTagKeys,
				}
				_, err = t.Cloud.IAM().UntagRole(ctx, untagRequest)
				if err != nil {
					return fmt.Errorf("error untagging IAMRole: %v", err)
				}
			}
			if len(e.Tags) > 0 {
				tagRequest := &iam.TagRoleInput{
					RoleName: e.Name,
					Tags:     mapToIAMTags(e.Tags),
				}
				_, err = t.Cloud.IAM().TagRole(ctx, tagRequest)
				if err != nil {
					return fmt.Errorf("error tagging IAMRole: %v", err)
				}
			}
		}
	}
	return nil
}

type terraformIAMRole struct {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Validate tag keys: 1-128 chars, letters/digits/spaces and _ . : / = + - @ only; fix the cluster spec tags
  2. For RequestLimitExceeded, retry with backoff or reduce parallel applies
  3. Grant iam:UntagRole (and iam:ListRoleTags) to the credentials
  4. For NoSuchEntity, re-run apply to refresh task state

Example fix

// before: reserved-prefix / overlong key
"tags": {"aws:legacy:env": "x", "<128+ char key>": "v"}

// after: compliant keys
"tags": {"Owner": "platform", "Cluster": "prod-eu"}
Defensive patterns

Strategy: retry

Validate before calling

func validIAMTagKey(k string) bool {
    if len(k) < 1 || len(k) > 128 { return false }
    re := regexp.MustCompile(`^[\p{L}\p{Z}\p{N}_.:/=+\-@]+$`)
    return re.MatchString(k)
}
for k := range tagsToRemove { if !validIAMTagKey(k) { return fmt.Errorf("invalid tag key %q", k) } }

Try / catch

// backoff on IAM throttling
for i := 0; i < 5; i++ {
    _, err := t.Cloud.IAM().UntagRole(ctx, req)
    if err == nil { break }
    if !strings.Contains(err.Error(), "RequestLimitExceeded") { return err }
    time.Sleep(time.Duration(1<<i) * time.Second)
}

Prevention

When it happens

Trigger: UntagRole returns NoSuchEntity (role deleted concurrently), InvalidInput (a tag key violates IAM rules — empty, over 128 chars, invalid characters — or too many keys), AccessDenied (missing iam:UntagRole), or RequestLimitExceeded throttling when many roles are updated at once.

Common situations: Cluster spec contains tags with characters IAM rejects (e.g. reserved aws: prefix, unsupported unicode); bulk apply across many roles triggering IAM throttling; external automation deleted the role mid-apply.

Related errors


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