kubernetes/kops · error
error parsing cloudformation policy document from JSON: %v
Error message
error parsing cloudformation policy document from JSON: %v
What it means
After URL-decoding, Find unmarshals the policy document as JSON so it can re-marshal it in a canonical, indented form for comparison. If the decoded document is not valid JSON, this error is returned and reconciliation of the policy aborts.
Source
Thrown at upup/pkg/fi/cloudup/awstasks/iamrolepolicy.go:126
p := response
actual.Role = &IAMRole{Name: p.RoleName}
if aws.ToString(e.Role.Name) == aws.ToString(p.RoleName) {
actual.Role.ID = e.Role.ID
}
if p.PolicyDocument != nil {
// The PolicyDocument is URI encoded (?)
policy := *p.PolicyDocument
policy, err = url.QueryUnescape(policy)
if err != nil {
return nil, fmt.Errorf("error parsing PolicyDocument for IAMRolePolicy %q: %v", aws.ToString(e.Name), err)
}
// Reformat the PolicyDocument by unmarshaling and re-marshaling to JSON.
// This will make it possible to compare it when using CloudFormation.
var jsonData interface{}
err = json.Unmarshal([]byte(policy), &jsonData)
if err != nil {
return nil, fmt.Errorf("error parsing cloudformation policy document from JSON: %v", err)
}
jsonBytes, err := json.MarshalIndent(jsonData, "", " ")
if err != nil {
return nil, fmt.Errorf("error converting cloudformation policy document to JSON: %v", err)
}
actual.PolicyDocument = fi.NewStringResource(string(jsonBytes))
}
actual.Name = p.PolicyName
e.ID = actual.ID
// Avoid spurious changes
actual.Lifecycle = e.Lifecycle
return &actual, nil
}
View on GitHub (pinned to 4c8573c808)
Solutions
- Validate the policy with `aws iam get-role-policy` output through a JSON linter
- Replace the malformed policy via `aws iam put-role-policy` with a valid JSON document
- Re-run `kops update cluster` to overwrite with the kops-managed policy
- Check for proxies/middles that could truncate the IAM response
Example fix
// validate the policy JSON before applying externally python3 -m json.tool policy.json # must succeed aws iam put-role-policy --role-name nodes --policy-name kops-policy --policy-document file://policy.json
Defensive patterns
Strategy: validation
Validate before calling
// validate stored policy is valid JSON before kops runs
out, _ := iamClient.GetRolePolicy(ctx, req)
decoded, _ := url.QueryUnescape(*out.PolicyDocument)
var v any
if err := json.Unmarshal([]byte(decoded), &v); err != nil {
// fix with aws iam put-role-policy
} Try / catch
if err := kopsUpdate(); err != nil {
if strings.Contains(err.Error(), "parsing cloudformation policy document") {
// overwrite the invalid policy with a valid JSON document, then retry
}
} Prevention
- Run policy JSON through a linter before applying anywhere
- Never create kops-named inline policies with hand-written JSON
- Verify no proxy truncates IAM API responses
- Use kops to regenerate the policy after detecting invalid JSON
When it happens
Trigger: GetRolePolicy returns a decoded PolicyDocument that fails json.Unmarshal — non-JSON content, truncated document, or JSON with unsupported constructs.
Common situations: Inline policy manually edited on AWS into invalid JSON; policy created by external tooling (e.g. YAML converted incorrectly); truncated response due to network/proxy issues.
Related errors
- error converting cloudformation policy document to JSON: %v
- error inline policy: %w
- additionalPolicy %q is invalid: %v
- error parsing expected RolePolicyDocument for IAMRole %q: %v
- error parsing actual RolePolicyDocument for IAMRole %q: %v
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/252017942e70585f.
Report an issue: GitHub.