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
- 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
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
- 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
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
- IP version is incorrect
- provider ID cannot be empty
- provider ID number cannot be empty
- writing keyset: %v
- error fetching cluster %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e95fe578b392e29e.
Report an issue: GitHub.