kubernetes/kops · error

error reading actual policy document: %v

Error message

error reading actual policy document: %v

What it means

During RenderAWS of an IAMRolePolicy, when the task has changes to apply, kOps re-reads the current inline policy from IAM via policyDocumentString() to compare with the desired policy before diffing/updating. This error wraps any failure of that read — most commonly the resource rendering of PolicyDocument or the local 10240-byte size guard inside policyDocumentString(). It aborts the apply for this task without modifying the IAM role policy.

Source

Thrown at upup/pkg/fi/cloudup/awstasks/iamrolepolicy.go:257

				return nil
			}
			return fmt.Errorf("error deleting IAMRolePolicy: %v", err)
		}
		return nil
	}

	doPut := false

	if a == nil {
		klog.V(2).Infof("Creating IAMRolePolicy")
		doPut = true
	} else if changes != nil {
		if changes.PolicyDocument != nil {
			klog.V(2).Infof("Applying changed role policy to %q:", *e.Name)

			actualPolicy, err := a.policyDocumentString()
			if err != nil {
				return fmt.Errorf("error reading actual policy document: %v", err)
			}

			if actualPolicy == policy {
				klog.Warning("Policies were actually the same")
			} else {
				d := diff.FormatDiff(actualPolicy, policy)
				klog.V(2).Infof("diff: %s", d)
			}

			doPut = true
		}
	}

	if doPut {
		request := &iam.PutRolePolicyInput{}
		request.PolicyDocument = aws.String(policy)
		request.RoleName = e.Role.Name
		request.PolicyName = e.Name

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check the wrapped inner error (%v) — if it reports policy size, trim statements or move permissions to a managed policy.
  2. Validate the PolicyDocument JSON is well-formed and readable before running kops update.
  3. Re-run kops update with --v=2 to see which role policy failed and inspect the cluster spec's additionalPolicies.
  4. Split the policy into a separately managed IAM managed policy and attach it by ARN.

Example fix

// before: one huge inline policy in cluster spec
additionalPolicies: [ <11KB JSON> ]
// after: trim or attach a managed policy
additionalPolicies: [ <condensed JSON with combined actions, wildcard resources where safe> ]
Defensive patterns

Strategy: validation

Validate before calling

policy, err := fi.ResourceAsString(task.PolicyDocument)
if err != nil { return err }
if len(strings.Join(strings.Fields(policy), "")) > 10240 { return fmt.Errorf("policy too large: %d bytes", len(policy)) }

Try / catch

// kops CLI: wrap the update call
if err := applyCluster(ctx, cluster); err != nil {
  if strings.Contains(err.Error(), "error reading actual policy document") {
    klog.Errorf("IAM role policy unreadable/oversized: %v", err)
  }
  return err
}

Prevention

When it happens

Trigger: Apply with changes to an IAMRolePolicy where fi.ResourceAsString(e.PolicyDocument) fails (unreadable/nil PolicyDocument resource), or the serialized policy exceeds 10240 bytes (the size guard inside policyDocumentString returns its own error which is wrapped here).

Common situations: Oversized inline role policies after adding many permissions; a PolicyDocument resource whose backing file/asset cannot be read at apply time; corrupted or empty policy resource after a partial build.

Related errors


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