kubernetes/kops · error

error reading expected RolePolicyDocument for IAMRole %q: %v

Error message

error reading expected RolePolicyDocument for IAMRole %q: %v

What it means

To compare desired vs actual trust policies, Find() reads the expected RolePolicyDocument from the task's resource via fi.ResourceAsString. If reading that embedded/remote resource fails, the error is wrapped with the role name. It indicates the spec-side policy content could not be loaded at all.

Source

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

	actual.ID = r.RoleId
	actual.Name = r.RoleName
	if r.PermissionsBoundary != nil {
		actual.PermissionsBoundary = r.PermissionsBoundary.PermissionsBoundaryArn
	}
	if r.AssumeRolePolicyDocument != nil {
		// The AssumeRolePolicyDocument is URI encoded (?)
		actualPolicy := *r.AssumeRolePolicyDocument
		actualPolicy, err = url.QueryUnescape(actualPolicy)
		if err != nil {
			return nil, fmt.Errorf("error parsing AssumeRolePolicyDocument for IAMRole %s: %v", *e.Name, err)
		}

		// The RolePolicyDocument is reformatted by AWS
		// We parse both as JSON; if the json forms are equal we pretend the actual value is the expected value
		if e.RolePolicyDocument != nil {
			expectedPolicy, err := fi.ResourceAsString(e.RolePolicyDocument)
			if err != nil {
				return nil, fmt.Errorf("error reading expected RolePolicyDocument for IAMRole %q: %v", aws.ToString(e.Name), err)
			}
			expectedJson := make(map[string]interface{})
			err = json.Unmarshal([]byte(expectedPolicy), &expectedJson)
			if err != nil {
				return nil, fmt.Errorf("error parsing expected RolePolicyDocument for IAMRole %q: %v", aws.ToString(e.Name), err)
			}
			actualJson := make(map[string]interface{})
			err = json.Unmarshal([]byte(actualPolicy), &actualJson)
			if err != nil {
				return nil, fmt.Errorf("error parsing actual RolePolicyDocument for IAMRole %q: %v", aws.ToString(e.Name), err)
			}

			if reflect.DeepEqual(actualJson, expectedJson) {
				klog.V(2).Infof("actual RolePolicyDocument was json-equal to expected; returning expected value")
				actualPolicy = expectedPolicy
			}
		}

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Verify the state store (S3) is accessible and the cluster manifest is intact
  2. Rebuild/refresh the task spec so RolePolicyDocument points at a valid resource
  3. Check kops version skew: re-run the same kops version that produced the manifest
  4. Restore the missing policy file/template referenced by the spec
Defensive patterns

Strategy: validation

Validate before calling

// confirm the expected policy resource resolves before reconcile
policyStr, err := fi.ResourceAsString(e.RolePolicyDocument)
if err != nil { return fmt.Errorf("expected RolePolicyDocument unreadable: %w", err) }
if policyStr == "" { return fmt.Errorf("expected RolePolicyDocument is empty") }

Try / catch

expectedPolicy, err := fi.ResourceAsString(e.RolePolicyDocument)
if err != nil {
    return nil, fmt.Errorf("error reading expected RolePolicyDocument for IAMRole %q: %w", aws.ToString(e.Name), err)
}

Prevention

When it happens

Trigger: fi.ResourceAsString(e.RolePolicyDocument) errors: the resource points to an unreadable asset (e.g. missing file, failed VFS read) referenced in the cluster spec.

Common situations: Cluster spec built with assets from a state store that is unreachable; custom role policy templates missing after repo/state migration; corrupted manifest in the kops state store.

Related errors


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