#17611·kyverno

[Bug] JSONPatch in MutatingPolicy causing crash in Kyverno

Author: SSvilenCreated Sep 17, 2026Updated Sep 18, 2026
Labelsbugtriage

Kyverno Version

v1.19.1

Description

We have the following mutating policy:

yaml
  mutations:
  - patchType: JSONPatch
    jsonPatch:
      expression: |
        has(object.spec.tolerations) ?
        [
          JSONPatch{
            op: "add",
            path: "/spec/tolerations/-",
            value: Object.spec.tolerations{
              key: "kubernetes.azure.com/scalesetpriority",
              operator: "Equal",
              value: "spot",
              effect: "NoSchedule"
            }
          }
        ] :
        [
          JSONPatch{
            op: "add",
            path: "/spec/tolerations",
            value: Object.spec.tolerations{
                key: "kubernetes.azure.com/scalesetpriority",
                operator: "Equal",
                value: "spot",
                effect: "NoSchedule"
              }
          }
        ]
  - patchType: JSONPatch
    jsonPatch:
      expression: |
        has(object.spec.affinity) && has(object.spec.affinity.nodeAffinity) && has(object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution) ?
        [
          JSONPatch{
            op: "add",
            path: "/spec/affinity/nodeAffinity/preferredDuringSchedulingIgnoredDuringExecution/-",
            value: Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution{
              weight: 100,
              preference: Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference{
                matchExpressions: [
                  Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference.matchExpressions{
                    key: "kubernetes.azure.com/scalesetpriority",
                    operator: "In",
                    values: ["spot"]
                  }
                ]
              }
            }
          }
        ] : has(object.spec.affinity) && has(object.spec.affinity.nodeAffinity) ?
        [
          JSONPatch{
            op: "add",
            path: "/spec/affinity/nodeAffinity/preferredDuringSchedulingIgnoredDuringExecution",
            value: [
              Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution{
                weight: 100,
                preference: Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference{
                  matchExpressions: [
                    Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference.matchExpressions{
                      key: "kubernetes.azure.com/scalesetpriority",
                      operator: "In",
                      values: ["spot"]
                    }
                  ]
                }
              }
            ]
          }
        ] : has(object.spec.affinity) ?
        [
          JSONPatch{
            op: "add",
            path: "/spec/affinity/nodeAffinity",
            value: Object.spec.affinity.nodeAffinity{
              preferredDuringSchedulingIgnoredDuringExecution: [
                Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution{
                  weight: 100,
                  preference: Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference{
                    matchExpressions: [
                      Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference.matchExpressions{
                        key: "kubernetes.azure.com/scalesetpriority",
                        operator: "In",
                        values: ["spot"]
                      }
                    ]
                  }
                }
              ]
            }
          }
        ] :
        [
          JSONPatch{
            op: "add",
            path: "/spec/affinity",
            value: Object.spec.affinity{
              nodeAffinity: Object.spec.affinity.nodeAffinity{
                preferredDuringSchedulingIgnoredDuringExecution: [
                  Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution{
                    weight: 100,
                    preference: Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference{
                      matchExpressions: [
                        Object.spec.affinity.nodeAffinity.preferredDuringSchedulingIgnoredDuringExecution.preference.matchExpressions{
                          key: "kubernetes.azure.com/scalesetpriority",
                          operator: "In",
                          values: ["spot"]
                        }
                      ]
                    }
                  }
                ]
              }
            }
          }
        ]

The second JSON patch (I know that for a fact, because removing it fixes all issues) is causing crash in the policy reporter:

Observed a panic logger=klog panic="reflect.Set: value of type *structpb.Struct is not assignable to type *structpb.Value" stacktrace="goroutine 3319 [running]:\nk8s.io/apimachinery/pkg/util/runtime.logPanic({0x5561d00, 0x5cfb164d140}, {0x4341100, 0x5cfaff47190})\n\tk8s.io/[email protected]/pkg/util/runtime/runtime.go:134 +0xbc\nk8s.io/apimachinery/pkg/util/runtime.handleCrash({0x5561d38, 0x5cfb1ae4370}, {0x4341100, 0x5cfaff47190}, {0x0, 0x0, 0x5cfb1a0afe8?})\n\tk8s.io/[email protected]/pkg/util/runtime/runtime.go:109 +0x116\nk8s.io/apimachinery/pkg/util/runtime.HandleCrashWithContext({0x5561d38, 0x5cfb1ae4370}, {0x0, 0x0, 0x0})\n\tk8s.io/[email protected]/pkg/util/runtime/runtime.go:80 +0x55\npanic({0x4341100?, 0x5cfaff47190?})\n\truntime/panic.go:860 +0x13a\nreflect.Value.assignTo({0x4b0e920?, 0x5cfb164cfc0?, 0x0?}, {0x4e95d5b, 0xb}, 0x4cb0120, 0x0)\n\treflect/value.go:3215 +0x288\nreflect.Value.Set({0x4cb0120?, 0x5cfb05aca48?, 0x4cb0120?}, {0x4b0e920?, 0x5cfb164cfc0?, 0x5cfb1a0b228?})\n\treflect/value.go:2158 +0xe6\ngithub.com/google/cel-go/common/types.(*baseList).ConvertToNative(0x5cfb164cbd0, {0x55d6c40?, 0x42aaf40?})\n\tgithub.com/google/[email protected]/common/types/list.go:200 +0x5ec\ngithub.com/google/cel-go/common/types.(*baseList).ConvertToNative(0x5cfb164cbd0, {0x55d6c40?, 0x4cb0120?})\n\tgithub.com/google/[email protected]/common/types/list.go:168 +0x1e8\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*jsonPatcher).evaluatePatchExpression(0x5cfb16e2dc0?, {0x5561d38?, 0x5cfb1ae4370?}, 0x989680, 0x28?)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/json.go:148 +0x695\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*jsonPatcher).Patch(0x5cfb0bef6c0?, {0x5561d38?, 0x5cfb1ae4370?}, 0x0?, {{{0x0, 0x0}, {0x5cfb08889f0, 0x2}, {0x5cfb08894c8, 0x4}}, ...}, ...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/json.go:57 +0x3b\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*Policy).evaluate(_, {_, _}, {_, _}, _, {{0x0, 0x0}, {{0x0, 0x0}, ...}, ...}, ...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/policy.go:234 +0x978\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*Policy).Evaluate(...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/policy.go:132\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*engineImpl).handlePolicy(_, {_, _}, {{_, _}, _, _}, {_, _}, {{0x0, ...}, ...}, ...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/engine.go:219 +0x4bb\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*engineImpl).Handle(_, {_, _}, {0x0, {{0x0, 0x0}, {{0x0, 0x0}, {0x5cfaf2e597e, 0x2}, ...}, ...}, ...}, ...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/engine.go:158 +0x7d0\ngithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*metricWrapper).Handle(_, {_, _}, {0x0, {{0x0, 0x0}, {{0x0, 0x0}, {0x5cfaf2e597e, 0x2}, ...}, ...}, ...}, ...)\n\tgithub.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/metrics.go:37 +0xb9\ngithub.com/kyverno/kyverno/pkg/controllers/report/utils.(*scanner).ScanResource(0x5cfb1a10680, {0x5561d38, 0x5cfb1ae4370}, {0x5cfb1f05e30}, {{0x0, 0x0}, {0x5cfb08889f0, 0x2}, {0x5cfb08894c8, 0x4}}, ...)\n\tgithub.com/kyverno/kyverno/pkg/controllers/report/utils/scanner.go:257 +0x2982\ngithub.com/kyverno/kyverno/pkg/controllers/report/background.(*controller).reconcileReport(_, {_, _}, {_, _}, {_, _}, _, {0x5cfb0da714c, 0x24}, ...)\n\tgithub.com/kyverno/kyverno/pkg/controllers/report/background/controller.go:735 +0x22a9\ngithub.com/kyverno/kyverno/pkg/controllers/report/background.(*controller).reconcile(0x5cfb06ffd48, {0x5561d38, 0x5cfb1ae4370}, {{0x21?, 0x3?}, 0x5579878?}, {0x5cfb0da7140, 0x30}, {0x5cfb0da7140, 0xb}, ...)\n\tgithub.com/kyverno/kyverno/pkg/controllers/report/background/controller.go:983 +0x3e37\ngithub.com/kyverno/kyverno/pkg/utils/controller.reconcile({0x5561d38, 0x5cfb1ae4370}, {{0x5579878?, 0x5cfb1ada320?}, 0x5cfb0140640?}, {0x4341100, 0x5cfb1a13bf8}, 0x5cfb1ae3a40)\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:110 +0x418\ngithub.com/kyverno/kyverno/pkg/utils/controller.processNextWorkItem[...]({0x5561d38, 0x5cfb1ae4370}, {{0x5579878, 0x5cfb1ada320?}, 0x5561d00?}, {0x4ed40ff?, 0x1a}, {0x5596d00, 0x5cfb0684920}, 0xa, ...)\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:60 +0x173\ngithub.com/kyverno/kyverno/pkg/utils/controller.worker[...](...)\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:53\ngithub.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1.1.1()\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:35 +0x110\nk8s.io/apimachinery/pkg/util/wait.BackoffUntilWithContext.func1({0x5561d38?, 0x5cfb1ae4370?}, 0x5cfb1ad3ce0?)\n\tk8s.io/[email protected]/pkg/util/wait/backoff.go:255 +0x51\nk8s.io/apimachinery/pkg/util/wait.BackoffUntilWithContext({0x5561d38, 0x5cfb1ae4370}, 0x5cfb1a13f00, {0x55121a0, 0x5cfb1ad3ce0}, 0x1)\n\tk8s.io/[email protected]/pkg/util/wait/backoff.go:256 +0xe5\nk8s.io/apimachinery/pkg/util/wait.JitterUntilWithContext({0x5561d38, 0x5cfb1ae4370}, 0x5cfaf4a3f00, 0x3b9aca00, 0x0, 0x1)\n\tk8s.io/[email protected]/pkg/util/wait/backoff.go:223 +0x8f\nk8s.io/apimachinery/pkg/util/wait.UntilWithContext({0x5561d38?, 0x5cfb1ae4370?}, 0x8?, 0x4ea3058?)\n\tk8s.io/[email protected]/pkg/util/wait/backoff.go:172 +0x25\ngithub.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1.1()\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:35 +0x22b\ncreated by github.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1 in goroutine 3317\n\tgithub.com/kyverno/kyverno/pkg/utils/controller/run.go:31 +0xfb\n"
panic: reflect.Set: value of type *structpb.Struct is not assignable to type *structpb.Value [recovered, repanicked]
goroutine 3319 [running]:
k8s.io/apimachinery/pkg/util/runtime.handleCrash({0x5561d38, 0x5cfb1ae4370}, {0x4341100, 0x5cfaff47190}, {0x0, 0x0, 0x5cfb1a0afe8?})
k8s.io/[email protected]/pkg/util/runtime/runtime.go:116 +0x1a9
k8s.io/apimachinery/pkg/util/runtime.HandleCrashWithContext({0x5561d38, 0x5cfb1ae4370}, {0x0, 0x0, 0x0})
k8s.io/[email protected]/pkg/util/runtime/runtime.go:80 +0x55
panic({0x4341100?, 0x5cfaff47190?})
runtime/panic.go:860 +0x13a
reflect.Value.assignTo({0x4b0e920?, 0x5cfb164cfc0?, 0x0?}, {0x4e95d5b, 0xb}, 0x4cb0120, 0x0)
reflect/value.go:3215 +0x288
reflect.Value.Set({0x4cb0120?, 0x5cfb05aca48?, 0x4cb0120?}, {0x4b0e920?, 0x5cfb164cfc0?, 0x5cfb1a0b228?})
reflect/value.go:2158 +0xe6
github.com/google/cel-go/common/types.(*baseList).ConvertToNative(0x5cfb164cbd0, {0x55d6c40?, 0x42aaf40?})
github.com/google/[email protected]/common/types/list.go:200 +0x5ec
github.com/google/cel-go/common/types.(*baseList).ConvertToNative(0x5cfb164cbd0, {0x55d6c40?, 0x4cb0120?})
github.com/google/[email protected]/common/types/list.go:168 +0x1e8
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*jsonPatcher).evaluatePatchExpression(0x5cfb16e2dc0?, {0x5561d38?, 0x5cfb1ae4370?}, 0x989680, 0x28?)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/json.go:148 +0x695
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*jsonPatcher).Patch(0x5cfb0bef6c0?, {0x5561d38?, 0x5cfb1ae4370?}, 0x0?, {{{0x0, 0x0}, {0x5cfb08889f0, 0x2}, {0x5cfb08894c8, 0x4}}, ...}, ...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/json.go:57 +0x3b
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*Policy).evaluate(_, {_, _}, {_, _}, _, {{0x0, 0x0}, {{0x0, 0x0}, ...}, ...}, ...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/policy.go:234 +0x978
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler.(*Policy).Evaluate(...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/compiler/policy.go:132
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*engineImpl).handlePolicy(_, {_, _}, {{_, _}, _, _}, {_, _}, {{0x0, ...}, ...}, ...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/engine.go:219 +0x4bb
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*engineImpl).Handle(_, {_, _}, {0x0, {{0x0, 0x0}, {{0x0, 0x0}, {0x5cfaf2e597e, 0x2}, ...}, ...}, ...}, ...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/engine.go:158 +0x7d0
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine.(*metricWrapper).Handle(_, {_, _}, {0x0, {{0x0, 0x0}, {{0x0, 0x0}, {0x5cfaf2e597e, 0x2}, ...}, ...}, ...}, ...)
github.com/kyverno/kyverno/pkg/cel/policies/mpol/engine/metrics.go:37 +0xb9
github.com/kyverno/kyverno/pkg/controllers/report/utils.(*scanner).ScanResource(0x5cfb1a10680, {0x5561d38, 0x5cfb1ae4370}, {0x5cfb1f05e30}, {{0x0, 0x0}, {0x5cfb08889f0, 0x2}, {0x5cfb08894c8, 0x4}}, ...)
github.com/kyverno/kyverno/pkg/controllers/report/utils/scanner.go:257 +0x2982
github.com/kyverno/kyverno/pkg/controllers/report/background.(*controller).reconcileReport(_, {_, _}, {_, _}, {_, _}, _, {0x5cfb0da714c, 0x24}, ...)
github.com/kyverno/kyverno/pkg/controllers/report/background/controller.go:735 +0x22a9
github.com/kyverno/kyverno/pkg/controllers/report/background.(*controller).reconcile(0x5cfb06ffd48, {0x5561d38, 0x5cfb1ae4370}, {{0x21?, 0x3?}, 0x5579878?}, {0x5cfb0da7140, 0x30}, {0x5cfb0da7140, 0xb}, ...)
github.com/kyverno/kyverno/pkg/controllers/report/background/controller.go:983 +0x3e37
github.com/kyverno/kyverno/pkg/utils/controller.reconcile({0x5561d38, 0x5cfb1ae4370}, {{0x5579878?, 0x5cfb1ada320?}, 0x5cfb0140640?}, {0x4341100, 0x5cfb1a13bf8}, 0x5cfb1ae3a40)
github.com/kyverno/kyverno/pkg/utils/controller/run.go:110 +0x418
github.com/kyverno/kyverno/pkg/utils/controller.processNextWorkItem[...]({0x5561d38, 0x5cfb1ae4370}, {{0x5579878, 0x5cfb1ada320?}, 0x5561d00?}, {0x4ed40ff?, 0x1a}, {0x5596d00, 0x5cfb0684920}, 0xa, ...)
github.com/kyverno/kyverno/pkg/utils/controller/run.go:60 +0x173
github.com/kyverno/kyverno/pkg/utils/controller.worker[...](...)
github.com/kyverno/kyverno/pkg/utils/controller/run.go:53
github.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1.1.1()
github.com/kyverno/kyverno/pkg/utils/controller/run.go:35 +0x110
k8s.io/apimachinery/pkg/util/wait.BackoffUntilWithContext.func1({0x5561d38?, 0x5cfb1ae4370?}, 0x5cfb1ad3ce0?)
k8s.io/[email protected]/pkg/util/wait/backoff.go:255 +0x51
k8s.io/apimachinery/pkg/util/wait.BackoffUntilWithContext({0x5561d38, 0x5cfb1ae4370}, 0x5cfb1a13f00, {0x55121a0, 0x5cfb1ad3ce0}, 0x1)
k8s.io/[email protected]/pkg/util/wait/backoff.go:256 +0xe5
k8s.io/apimachinery/pkg/util/wait.JitterUntilWithContext({0x5561d38, 0x5cfb1ae4370}, 0x5cfaf4a3f00, 0x3b9aca00, 0x0, 0x1)
k8s.io/[email protected]/pkg/util/wait/backoff.go:223 +0x8f
k8s.io/apimachinery/pkg/util/wait.UntilWithContext({0x5561d38?, 0x5cfb1ae4370?}, 0x8?, 0x4ea3058?)
k8s.io/[email protected]/pkg/util/wait/backoff.go:172 +0x25
github.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1.1()
github.com/kyverno/kyverno/pkg/utils/controller/run.go:35 +0x22b
created by github.com/kyverno/kyverno/pkg/utils/controller.Run[...].func1 in goroutine 3317
github.com/kyverno/kyverno/pkg/utils/controller/run.go:31 +0xfb

The policy also can not be applied:

Error creating: Internal error occurred: failed calling webhook "mpol.validate.kyverno.svc-fail-finegrained-add-spot-tolerations-cel": failed to call webhook: Post "https://aks-01-kyverno-svc.kyverno-policy-engine.svc:443/mpol/add-spot-tolerations-cel?timeout=10s": EOF

Test with https://playground.kyverno.io/ is successful.

Slack discussion

No response

Troubleshooting

  • I have read and followed the documentation AND the troubleshooting guide.
  • I have searched other issues in this repository and mine is not recorded.