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
- 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.
- 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.
- Run `kops update cluster -v=8` to see the wrapped inner error (the %w chain) and address the specific policy-library failure it reports.
- 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
- Always set cluster.spec region/account ID correctly before enabling node termination handler.
- Unwrap the %w chain (`errors.Unwrap` or `%+v`) to see the underlying iam-policy error, not just the wrapper.
- When running on non-commercial partitions (govcloud, cn), verify kops supports that partition for ARN generation.
- Keep kops updated; policy serialization bugs in pkg/iam are fixed in patch releases.
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
- error deleting SQS queue %q: %w
- error listing SQS queues: %v
- IP version is incorrect
- provider ID cannot be empty
- provider ID number cannot be empty
AI-assisted analysis of kubernetes/kops@4c8573c808 (2026-09-05).
Data as JSON: /api/errors/e7e4653769dbbf6b.
Report an issue: GitHub.