{"record":{"id":"e7e4653769dbbf6b","repo":"kubernetes/kops","slug":"rendering-policy-as-json-w","errorCode":null,"errorMessage":"rendering policy as json: %w","messagePattern":"rendering policy as json: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/model/awsmodel/nodeterminationhandler.go","lineNumber":137,"sourceCode":"\tarn := arn.ARN{\n\t\tPartition: b.AWSPartition,\n\t\tService:   \"sqs\",\n\t\tRegion:    b.Region,\n\t\tAccountID: b.AWSAccountID,\n\t\tResource:  queueName,\n\t}\n\n\tpolicy.Statement = append(policy.Statement, &iam.Statement{\n\t\tEffect: iam.StatementEffectAllow,\n\t\tPrincipal: iam.Principal{\n\t\t\tService: new(stringorset.Of(\"events.amazonaws.com\", \"sqs.amazonaws.com\")),\n\t\t},\n\t\tAction:   stringorset.Of(\"sqs:SendMessage\"),\n\t\tResource: stringorset.String(arn.String()),\n\t})\n\tpolicyJSON, err := policy.AsJSON()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"rendering policy as json: %w\", err)\n\t}\n\n\tqueue := &awstasks.SQS{\n\t\tName:                   aws.String(queueName),\n\t\tLifecycle:              b.Lifecycle,\n\t\tPolicy:                 fi.NewStringResource(policyJSON),\n\t\tMessageRetentionPeriod: DefaultMessageRetentionPeriod,\n\t\tTags:                   b.CloudTags(queueName, false),\n\t}\n\n\tc.AddTask(queue)\n\n\tclusterName := b.ClusterName()\n\n\tclusterNamePrefix := awsup.GetClusterName40(clusterName)\n\n\tevents := append([]event(nil), fixedEvents...)\n\tif b.Cluster.Spec.CloudProvider.AWS.NodeTerminationHandler != nil && fi.ValueOf(b.Cluster.Spec.CloudProvider.AWS.NodeTerminationHandler.EnableRebalanceDraining) {","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/kubernetes/kops/blob/4c8573c808a73d578c5eadc86d410646ea0b0d73/pkg/model/awsmodel/nodeterminationhandler.go#L119-L155","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before: empty region/account in build context causes bad ARN\narn := arn.ARN{Partition: b.AWSPartition, Service: \"sqs\", Region: b.Region, AccountID: b.AWSAccountID, Resource: queueName}\n// after: guard against empty values before rendering\nif b.Region == \"\" || b.AWSAccountID == \"\" {\n    return fmt.Errorf(\"region and account ID must be set to build NTH queue policy\")\n}\narn := arn.ARN{Partition: b.AWSPartition, Service: \"sqs\", Region: b.Region, AccountID: b.AWSAccountID, Resource: queueName}","handlingStrategy":"try-catch","validationCode":"// Sanity-check the inputs that feed the SQS ARN before building\nif b.Region == \"\" || b.AWSAccountID == \"\" || b.AWSPartition == \"\" {\n    return fmt.Errorf(\"cannot build NTH policy: region/account/partition unset\")\n}","typeGuard":"func validARNInputs(region, accountID, partition string) bool {\n    return region != \"\" && accountID != \"\" && partition != \"\"\n}","tryCatchPattern":"if err := b.build(c); err != nil {\n    var perr *json.MarshalTypeError\n    if errors.As(err, &perr) || strings.Contains(err.Error(), \"rendering policy as json\") {\n        return fmt.Errorf(\"NTH SQS policy render failed (check region/account/partition): %w\", err)\n    }\n    return err\n}","preventionTips":["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."],"tags":["aws","iam","sqs","json-serialization"],"backgroundTag":"policy-json-render-failed","analyzedSha":"4c8573c808a73d578c5eadc86d410646ea0b0d73","analyzedAt":"2026-09-05T04:13:19.212Z","contentChangedAt":"2026-09-05T04:13:19.212Z","schemaVersion":2},"datasetVersion":"2026-09-12T07:17:12.445Z"}