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

  1. Validate the policy with `aws iam get-role-policy` output through a JSON linter
  2. Replace the malformed policy via `aws iam put-role-policy` with a valid JSON document
  3. Re-run `kops update cluster` to overwrite with the kops-managed policy
  4. 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

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


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