{"record":{"id":"e95fe578b392e29e","repo":"kubernetes/kops","slug":"error-reading-expected-rolepolicydocument-for-iamr","errorCode":null,"errorMessage":"error reading expected RolePolicyDocument for IAMRole %q: %v","messagePattern":"error reading expected RolePolicyDocument for IAMRole %q: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"upup/pkg/fi/cloudup/awstasks/iamrole.go","lineNumber":98,"sourceCode":"\tactual.ID = r.RoleId\n\tactual.Name = r.RoleName\n\tif r.PermissionsBoundary != nil {\n\t\tactual.PermissionsBoundary = r.PermissionsBoundary.PermissionsBoundaryArn\n\t}\n\tif r.AssumeRolePolicyDocument != nil {\n\t\t// The AssumeRolePolicyDocument is URI encoded (?)\n\t\tactualPolicy := *r.AssumeRolePolicyDocument\n\t\tactualPolicy, err = url.QueryUnescape(actualPolicy)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"error parsing AssumeRolePolicyDocument for IAMRole %s: %v\", *e.Name, err)\n\t\t}\n\n\t\t// The RolePolicyDocument is reformatted by AWS\n\t\t// We parse both as JSON; if the json forms are equal we pretend the actual value is the expected value\n\t\tif e.RolePolicyDocument != nil {\n\t\t\texpectedPolicy, err := fi.ResourceAsString(e.RolePolicyDocument)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error reading expected RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\t\t\texpectedJson := make(map[string]interface{})\n\t\t\terr = json.Unmarshal([]byte(expectedPolicy), &expectedJson)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing expected RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\t\t\tactualJson := make(map[string]interface{})\n\t\t\terr = json.Unmarshal([]byte(actualPolicy), &actualJson)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, fmt.Errorf(\"error parsing actual RolePolicyDocument for IAMRole %q: %v\", aws.ToString(e.Name), err)\n\t\t\t}\n\n\t\t\tif reflect.DeepEqual(actualJson, expectedJson) {\n\t\t\t\tklog.V(2).Infof(\"actual RolePolicyDocument was json-equal to expected; returning expected value\")\n\t\t\t\tactualPolicy = expectedPolicy\n\t\t\t}\n\t\t}\n","sourceCodeStart":80,"sourceCodeEnd":116,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/upup/pkg/fi/cloudup/awstasks/iamrole.go#L80-L116","documentation":"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.","triggerScenarios":"fi.ResourceAsString(e.RolePolicyDocument) errors: the resource points to an unreadable asset (e.g. missing file, failed VFS read) referenced in the cluster spec.","commonSituations":"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.","solutions":["Verify the state store (S3) is accessible and the cluster manifest is intact","Rebuild/refresh the task spec so RolePolicyDocument points at a valid resource","Check kops version skew: re-run the same kops version that produced the manifest","Restore the missing policy file/template referenced by the spec"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// confirm the expected policy resource resolves before reconcile\npolicyStr, err := fi.ResourceAsString(e.RolePolicyDocument)\nif err != nil { return fmt.Errorf(\"expected RolePolicyDocument unreadable: %w\", err) }\nif policyStr == \"\" { return fmt.Errorf(\"expected RolePolicyDocument is empty\") }","typeGuard":null,"tryCatchPattern":"expectedPolicy, err := fi.ResourceAsString(e.RolePolicyDocument)\nif err != nil {\n    return nil, fmt.Errorf(\"error reading expected RolePolicyDocument for IAMRole %q: %w\", aws.ToString(e.Name), err)\n}","preventionTips":["Keep the state store reachable and consistent before updates","Verify referenced policy assets/templates exist in the repo","Restore/verify manifests after migrations","Use the same kops version that created the cluster spec"],"tags":["aws","iam","resource-read","state-store"],"backgroundTag":"resource-read-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}