kubernetes/kops · error

rendering policy as json: %w

Error message

rendering policy as json: %w

What it means

The NodeTerminationHandler builder constructs an IAM policy (allowing events.amazonaws.com/sqs.amazonaws.com to sqs:SendMessage on the NTH SQS queue) and serializes it with policy.AsJSON(). This error wraps any failure from that serialization — typically the IAM policy document being invalid or unserializable — and aborts the cluster model build before the SQS task is created. The original error from the IAM policy library is preserved via %w.

Source

Thrown at pkg/model/awsmodel/nodeterminationhandler.go:137

	arn := arn.ARN{
		Partition: b.AWSPartition,
		Service:   "sqs",
		Region:    b.Region,
		AccountID: b.AWSAccountID,
		Resource:  queueName,
	}

	policy.Statement = append(policy.Statement, &iam.Statement{
		Effect: iam.StatementEffectAllow,
		Principal: iam.Principal{
			Service: new(stringorset.Of("events.amazonaws.com", "sqs.amazonaws.com")),
		},
		Action:   stringorset.Of("sqs:SendMessage"),
		Resource: stringorset.String(arn.String()),
	})
	policyJSON, err := policy.AsJSON()
	if err != nil {
		return fmt.Errorf("rendering policy as json: %w", err)
	}

	queue := &awstasks.SQS{
		Name:                   aws.String(queueName),
		Lifecycle:              b.Lifecycle,
		Policy:                 fi.NewStringResource(policyJSON),
		MessageRetentionPeriod: DefaultMessageRetentionPeriod,
		Tags:                   b.CloudTags(queueName, false),
	}

	c.AddTask(queue)

	clusterName := b.ClusterName()

	clusterNamePrefix := awsup.GetClusterName40(clusterName)

	events := append([]event(nil), fixedEvents...)
	if b.Cluster.Spec.CloudProvider.AWS.NodeTerminationHandler != nil && fi.ValueOf(b.Cluster.Spec.CloudProvider.AWS.NodeTerminationHandler.EnableRebalanceDraining) {

View on GitHub (pinned to 4c8573c808)

Solutions

  1. Check that the cluster spec has a valid AWS region, account ID, and partition — empty or malformed values flow into the SQS ARN used by the policy.
  2. Upgrade (or pin) kops to a version where the iam policy AsJSON bug is fixed; search kops releases for changes to pkg/iam or nodeterminationhandler.
  3. Run `kops update cluster -v=8` to see the wrapped inner error (the %w chain) and address the specific policy-library failure it reports.
  4. If building from source, inspect the inner error from policy.AsJSON() and validate the generated statement (Principal/Action/Resource types) in pkg/model/awsmodel/nodeterminationhandler.go.

Example fix

// before: empty region/account in build context causes bad ARN
arn := arn.ARN{Partition: b.AWSPartition, Service: "sqs", Region: b.Region, AccountID: b.AWSAccountID, Resource: queueName}
// after: guard against empty values before rendering
if b.Region == "" || b.AWSAccountID == "" {
    return fmt.Errorf("region and account ID must be set to build NTH queue policy")
}
arn := arn.ARN{Partition: b.AWSPartition, Service: "sqs", Region: b.Region, AccountID: b.AWSAccountID, Resource: queueName}
Defensive patterns

Strategy: try-catch

Validate before calling

// Sanity-check the inputs that feed the SQS ARN before building
if b.Region == "" || b.AWSAccountID == "" || b.AWSPartition == "" {
    return fmt.Errorf("cannot build NTH policy: region/account/partition unset")
}

Type guard

func validARNInputs(region, accountID, partition string) bool {
    return region != "" && accountID != "" && partition != ""
}

Try / catch

if err := b.build(c); err != nil {
    var perr *json.MarshalTypeError
    if errors.As(err, &perr) || strings.Contains(err.Error(), "rendering policy as json") {
        return fmt.Errorf("NTH SQS policy render failed (check region/account/partition): %w", err)
    }
    return err
}

Prevention

When it happens

Trigger: `kops update cluster` (or controller code calling NodeTerminationHandlerBuilder.Build) when the generated policy cannot be marshalled to JSON, e.g. an invalid region/partition/account ID producing a malformed ARN, or a bug/change in the embedded iam policy package making the statement invalid.

Common situations: Corrupt or empty cluster config fields feeding b.AWSAccountID/b.Region/b.AWSPartition; running with a custom AWS partition (e.g. govcloud/us-gov, china) that the ARN formatting mishandles; a kops version regression in the vendored iam library.

Related errors


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