kubernetes/kops · error

calling IAM GetInstanceProfile on %s: %w

Error message

calling IAM GetInstanceProfile on %s: %w

What it means

kOps wraps the AWS SDK error from iam.GetInstanceProfile after a profile was listed. NoSuchEntity and 403 are already filtered out with warnings (treated as already-deleted / not-owned), so this error is a genuinely unexpected failure fetching the profile detail used to inspect ownership tags. Note the message uses %w so errors.Is/As against smithy API errors works.

Source

Thrown at pkg/resources/aws/aws.go:2097

	for paginator.HasMorePages() {
		page, err := paginator.NextPage(ctx)
		if err != nil {
			return nil, fmt.Errorf("error listing IAM instance profiles: %v", err)
		}
		for _, p := range page.InstanceProfiles {
			name := aws.ToString(p.InstanceProfileName)

			getRequest := &iam.GetInstanceProfileInput{InstanceProfileName: p.InstanceProfileName}
			profileOutput, err := c.IAM().GetInstanceProfile(ctx, getRequest)
			if err != nil {
				if awsup.IsIAMNoSuchEntityException(err) {
					klog.Warningf("could not find role %q. Resource may already have been deleted: %v", name, err)
					continue
				} else if awsup.AWSErrorCode(err) == "403" {
					klog.Warningf("failed to determine ownership of %q: %v", *p.InstanceProfileName, err)
					continue
				}
				return nil, fmt.Errorf("calling IAM GetInstanceProfile on %s: %w", name, err)
			}
			for _, tag := range profileOutput.InstanceProfile.Tags {
				if fi.ValueOf(tag.Key) == ownershipTag && fi.ValueOf(tag.Value) == "owned" {
					profiles = append(profiles, p)
				}
			}
		}
	}

	var resourceTrackers []*resources.Resource

	for _, profile := range profiles {
		name := aws.ToString(profile.InstanceProfileName)
		resourceTracker := &resources.Resource{
			Name:    name,
			ID:      name,
			Type:    "iam-instance-profile",
			Deleter: DeleteIAMInstanceProfile,

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped AWS error code via awsup.AWSErrorCode(err) or errors.As to identify the cause
  2. If throttled, retry with backoff or reduce parallelism
  3. If the profile was deleted concurrently, re-run the operation — the list is now stale
  4. Verify credentials and region are correct for the cluster
Defensive patterns

Strategy: retry

Validate before calling

// preflight permission check
_, err := iamClient.GetInstanceProfile(ctx, &iam.GetInstanceProfileInput{InstanceProfileName: aws.String(name)})
// ignore NotFound/403; fail fast on other codes before batch work

Type guard

func isRetryableIAM(err error) bool {
  var ae smithy.APIError
  return errors.As(err, &ae) && (ae.ErrorCode() == "ThrottlingException" || ae.ErrorCode() == "TooManyRequests" || ae.ErrorCode() == "RequestLimitExceeded")
}

Try / catch

profiles, err := ListOwnedInstanceProfiles(ctx, cloud)
if err != nil {
  if isRetryableIAM(err) { /* exponential backoff retry */ }
  return fmt.Errorf("instance profile ownership scan failed: %w", err)
}

Prevention

When it happens

Trigger: GetInstanceProfile returns any error other than NoSuchEntityException and 403: throttling (TooManyRequests), AuthorizationQueryAccessDenied variants not matching the literal '403' code check, serialization or network errors.

Common situations: Mass deletions race with the listing (profile deleted between List and Get) — mitigated only for NoSuchEntity; heavy API usage causing IAM throttling; malformed instance profile state.

Related errors


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