agentleFS
foxj77foxj77/claude-code-skills/kyverno-troubleshooting/SKILL.md

kyverno-troubleshooting

Skill19 starsChanged 10 months agoMITView on GitHub

Use when Kyverno policies are blocking resource creation, when ClusterPolicy or Policy resources show errors, when audit results are unexpected, when mutations are not applying, when generate rules fail, or when admission webhook errors occur

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 2 are distinctive, and 0 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈2

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 0

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Distinctive:

    If Kyverno is blocking all cluster operations and cannot recover, recommend the following to the user:

    line 349
  2. Distinctive:

    When the appropriate MCP servers are connected, prefer these over raw kubectl where available:

    line 381

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Kyverno Troubleshooting

Diagnose failures in Kyverno — the Kubernetes-native policy engine that validates, mutates, generates, and cleans up resources using policies written as Kubernetes resources (no new language to learn).

Keywords

kyverno, policy, clusterpolicy, validate, mutate, generate, cleanup, admission, webhook, deny, block, enforce, audit, policyreport, clusterpolicyreport, rule, match, exclude, preconditions, background, policy-exception

When to Use This Skill

  • Resource creation is blocked with "admission webhook denied the request"
  • ClusterPolicy or Policy resources show errors or are not applied
  • Mutations are not being applied to resources as expected
  • Generate rules are not creating expected resources
  • Policy reports show unexpected violations
  • Webhook timeouts or failures are disrupting cluster operations
  • Policies work in Audit mode but fail in Enforce mode
  • Background scan results are missing or incomplete

When NOT to Use

  • Resource creation fails but the error is not from an admission webhook → use k8s-namespace-troubleshooting
  • Kyverno policies are delivered by Flux and not appearing → use flux-troubleshooting
  • Pod Security Standards are enforced by the built-in PodSecurity admission (not Kyverno) → use k8s-security-hardening

Related Skills

  • cert-manager-troubleshooting - Policies may affect certificate resources
  • external-secrets-troubleshooting - Policies may block secret creation
  • external-dns-troubleshooting - Policies may restrict annotations
  • k8s-namespace-troubleshooting - General namespace diagnosis
  • k8s-security-hardening - Security policies and Pod Security Standards
  • k8s-platform-tenancy - Tenant isolation policies
  • flux-troubleshooting - GitOps delivery of Kyverno policies

Quick Reference

TaskCommand
Check Kyverno podskubectl get pods -n kyverno
List ClusterPolicieskubectl get clusterpolicy
List Policieskubectl get policy -A
Check policy statuskubectl get clusterpolicy -o wide
View policy reportskubectl get policyreport -A
View cluster policy reportskubectl get clusterpolicyreport
Check admission logskubectl logs -n kyverno deploy/kyverno-admission-controller --tail=200
Check background logskubectl logs -n kyverno deploy/kyverno-background-controller --tail=200
Test policy dry-runkubectl apply -f resource.yaml --dry-run=server

Diagnostic Workflow

Resource blocked by Kyverno?
├─ Identify which policy blocked it
│   ├─ Error message contains policy name → Check that policy (Section 2)
│   └─ Generic webhook error → Check webhook health (Section 1)
├─ Policy exists but not enforcing?
│   ├─ Policy status Ready: False → Spec error (Section 2)
│   ├─ validationFailureAction: Audit → Only reports, doesn't block (Section 3)
│   └─ match/exclude misconfigured → Wrong resource selection (Section 3)
├─ Mutation not applying?
│   ├─ Mutate rule exists → Check match criteria and patch (Section 4)
│   └─ Order matters → Check policy ordering (Section 4)
├─ Generate rule not creating resources?
│   ├─ Trigger resource matched? → Check match/preconditions (Section 5)
│   └─ RBAC sufficient? → Kyverno SA needs create permission (Section 5)
└─ Webhook causing cluster issues?
    └─ Timeouts or failOpen config (Section 7)

Section 1: Controller Health

# Check all Kyverno components
kubectl get pods -n kyverno -o wide

# Kyverno v1.10+ has multiple controllers:
# - kyverno-admission-controller (validates/mutates on admission)
# - kyverno-background-controller (background scans, generate, cleanup)
# - kyverno-reports-controller (policy reports)
# - kyverno-cleanup-controller (cleanup policies)

# Controller logs
kubectl logs -n kyverno deploy/kyverno-admission-controller --tail=200
kubectl logs -n kyverno deploy/kyverno-background-controller --tail=200
kubectl logs -n kyverno deploy/kyverno-reports-controller --tail=100

# Check CRDs
kubectl get crd | grep kyverno

# Check webhook configurations
kubectl get validatingwebhookconfigurations | grep kyverno
kubectl get mutatingwebhookconfigurations | grep kyverno

# Check webhook endpoints
kubectl get endpoints -n kyverno

Component Issues

ComponentSymptomDiagnostic
Admission controller downAll resource creates/updates fail or bypass policyCheck pod status for OOM/CrashLoop; recommend scaling up
Background controller downReports not generated, generate rules don't fireCheck pod logs and RBAC for background operations
Reports controller downMissing PolicyReport resourcesCheck pod status; may need significant memory for large clusters
Webhook cert expired"x509: certificate has expired" on admissionCheck webhook Secret expiry; recommend deleting webhook secret and restarting admission controller to regenerate
All Kyverno pods OOMLarge policy set or high cluster activityCheck memory usage vs limits; recommend increasing limits or reducing policy scope with match/exclude

Section 2: Policy Status and Validation

# Check ClusterPolicy status
kubectl get clusterpolicy -o wide
kubectl describe clusterpolicy ${POLICY_NAME}

# Check Policy status (namespace-scoped)
kubectl get policy -n ${NS} -o wide
kubectl describe policy ${POLICY_NAME} -n ${NS}

# Check for policy spec errors
kubectl get clusterpolicy ${POLICY_NAME} -o json | jq '.status'

# List all rules in a policy
kubectl get clusterpolicy ${POLICY_NAME} -o json | jq '.spec.rules[].name'

Policy Validation Errors

ErrorCauseDiagnostic
"rule is not valid"Invalid rule specCheck YAML syntax, pattern structure, and field names
"path not found"match or mutate references a field that doesn't existVerify the resource schema has the referenced path
"invalid pattern"Pattern value doesn't match expected typeCheck that field types match (string where string expected)
"conflict with existing policy"Two policies with conflicting mutationsIdentify conflicting policies; recommend resolving conflict or setting policy ordering
Policy Ready: FalseCompilation or validation failureCheck describe for the specific error message
"unknown field"Kyverno version doesn't support the fieldCheck Kyverno version compatibility

Section 3: Validate Rules — Audit vs Enforce

# Check validation failure action
kubectl get clusterpolicy ${POLICY_NAME} -o jsonpath='{.spec.validationFailureAction}'

# Check per-rule overrides
kubectl get clusterpolicy ${POLICY_NAME} -o json | jq '.spec.rules[] | {name: .name, action: .validate.validationFailureAction}'

# Check policy reports for audit violations
kubectl get policyreport -n ${NS} -o json | jq '.items[].results[] | select(.result == "fail") | {policy: .policy, rule: .rule, resource: .resources[0].name, message: .message}'

# Check cluster-level violations
kubectl get clusterpolicyreport -o json | jq '.items[].results[] | select(.result == "fail") | {policy: .policy, rule: .rule, resource: .resources[0].name}'

Audit vs Enforce

ModeBehaviourUse Case
AuditAllows the resource but reports violationTesting policies before enforcing
EnforceBlocks the resource if it violates the policyProduction enforcement
ProblemCauseDiagnostic
Policy not blocking anythingvalidationFailureAction: AuditVerify validationFailureAction value; recommend changing to Enforce when ready
Policy blocks everythingMatch criteria too broadCheck match scope; recommend adding exclude rules for system namespaces
Policy blocks some resources unexpectedlymatch includes resources you didn't intendCheck match criteria against affected resources; recommend adding exclude for exempted resources
Violations in report but resource existsAudit mode — resource was allowedVerify enforcement mode; recommend switching to Enforce to block

Match and Exclude Patterns

# Common pattern: enforce on all namespaces except system ones
spec:
  rules:
    - name: check-labels
      match:
        any:
          - resources:
              kinds:
                - Pod
      exclude:
        any:
          - resources:
              namespaces:
                - kube-system
                - kyverno
                - cert-manager

Section 4: Mutate Rules

# Check if mutation is configured
kubectl get clusterpolicy ${POLICY_NAME} -o json | jq '.spec.rules[] | select(.mutate) | {name: .name, mutate: .mutate}'

# Check if mutation was applied (compare resource against expected)
kubectl get ${RESOURCE_TYPE} ${NAME} -n ${NS} -o yaml | grep -A5 "expected-field"

# Check mutation webhook
kubectl get mutatingwebhookconfigurations kyverno-resource-mutating-webhook-cfg -o yaml

# Logs for mutation errors
kubectl logs -n kyverno deploy/kyverno-admission-controller --tail=200 | grep -iE 'mutate|patch'

Mutation Types

TypeUse CaseCommon Issue
patchStrategicMergeAdd/modify fields using K8s strategic mergeTarget path doesn't exist at admission time
patchesJson6902JSON patch operations (add, remove, replace)Wrong path or operation type
foreachMutate items in arrays (containers, volumes)Iterator variable scoping

Mutation Problems

ProblemCauseDiagnostic
Mutation not appliedMatch criteria don't select the resourceCheck match.resources.kinds, namespaces, selectors against target resource
Mutation partially appliedMultiple rules, one failedCheck each rule independently; look for errors in admission controller logs
Mutation conflicts with user valuesStrategic merge overwrites user fieldsCompare patch type; recommend using patchesJson6902 with add for conditional patches
Order-dependent mutationsPolicy A's mutation needed before Policy B validatesCheck policy ordering; recommend setting webhookConfiguration ordering or combining into one policy
Mutation applied but revertedAnother controller (e.g., Flux) reconciles the originalCheck if another controller manages the resource; recommend applying mutation at source (Git)

Section 5: Generate Rules

# Check generate rules
kubectl get clusterpolicy ${POLICY_NAME} -o json | jq '.spec.rules[] | select(.generate) | {name: .name, kind: .generate.kind}'

# Check background controller (handles generate)
kubectl logs -n kyverno deploy/kyverno-background-controller --tail=200 | grep -iE 'generate|trigger'

# Check if generated resources exist
kubectl get ${GENERATED_KIND} -n ${TARGET_NS}

# Check RBAC for generated resource type
kubectl auth can-i create ${GENERATED_KIND} --as=system:serviceaccount:kyverno:kyverno-background-controller -n ${TARGET_NS}

Generate Rule Patterns

# Generate NetworkPolicy when namespace is created
spec:
  rules:
    - name: default-deny
      match:
        any:
          - resources:
              kinds:
                - Namespace
      generate:
        synchronize: true       # Keep in sync (update if policy changes)
        apiVersion: networking.k8s.io/v1
        kind: NetworkPolicy
        name: default-deny
        namespace: "{{request.object.metadata.name}}"
        data:
          spec:
            podSelector: {}
            policyTypes:
              - Ingress
              - Egress

Generate Problems

ProblemCauseDiagnostic
Generated resource not createdBackground controller RBAC insufficientCheck RBAC with kubectl auth can-i; recommend granting create/update permissions
Trigger matched but nothing generatedPreconditions not metCheck preconditions in the rule against actual resource values
Generated resource deletedsynchronize: true and policy was removedCheck if sync is enabled; resources are cleaned up when policy/trigger is removed
Re-creation loopGenerated resource conflicts with another controllerCheck if another controller manages the resource; recommend disabling synchronize
Works for new resources but not existingGenerate only triggers on admission eventsVerify trigger type; recommend running a background scan

Section 6: Policy Exceptions

# List policy exceptions
kubectl get policyexception -A

# Check if an exception applies
kubectl get policyexception -A -o json | jq '.items[] | {name: .metadata.name, namespace: .metadata.namespace, policies: [.spec.exceptions[].policyName], match: .spec.match}'
ProblemCauseDiagnostic
Exception not workingFeature not enabledCheck if --enablePolicyException=true is set on admission controller args
Exception too broadExempts more resources than intendedReview match criteria in the PolicyException; recommend narrowing scope
Exception ignoredPolicyException namespace doesn't matchCheck if exception is in the correct namespace

Section 7: Webhook Issues

# Check webhook configuration
kubectl get validatingwebhookconfigurations kyverno-resource-validating-webhook-cfg -o yaml
kubectl get mutatingwebhookconfigurations kyverno-resource-mutating-webhook-cfg -o yaml

# Check webhook failure policy
kubectl get validatingwebhookconfigurations kyverno-resource-validating-webhook-cfg -o jsonpath='{.webhooks[*].failurePolicy}'

# Check webhook timeouts
kubectl get validatingwebhookconfigurations kyverno-resource-validating-webhook-cfg -o jsonpath='{.webhooks[*].timeoutSeconds}'

# Check namespace exclusions
kubectl get validatingwebhookconfigurations kyverno-resource-validating-webhook-cfg -o json | jq '.webhooks[].namespaceSelector'

Webhook Failure Modes

failurePolicyBehaviourRisk
Fail (default)Reject resource if webhook unreachableCluster operations blocked if Kyverno is down
IgnoreAllow resource if webhook unreachablePolicies bypassed during Kyverno outage

Webhook Problems

ProblemCauseDiagnostic
Webhook timeout (30s default)Complex policies or high loadCheck timeout setting and policy complexity; recommend increasing timeout or scaling replicas
"connection refused"Admission controller pod downCheck pod status and resource limits; recommend restarting pod
All creates blockedWebhook Fail + Kyverno downCheck failurePolicy and pod health; recommend scaling up Kyverno or temporarily setting Ignore (security risk)
Webhook blocks Kyverno itselfNo exclusion for kyverno namespaceCheck webhook namespaceSelector; recommend adding exclusion for kyverno namespace
Webhook blocks kube-systemNo exclusion for system namespacesCheck webhook namespaceSelector; recommend excluding kube-system, kube-node-lease, kube-public
cert error on webhookTLS certificate expiredCheck webhook Secret expiry; recommend deleting webhook secret and restarting admission controller

Emergency: Kyverno Blocking All Cluster Operations

If Kyverno is blocking all cluster operations and cannot recover, recommend the following to the user:

OptionCommand to RecommendEffect
Delete webhook configskubectl delete validatingwebhookconfigurations kyverno-resource-validating-webhook-cfg and kubectl delete mutatingwebhookconfigurations kyverno-resource-mutating-webhook-cfgDisables ALL policy enforcement; Kyverno recreates webhooks on restart
Scale down Kyvernokubectl scale deploy -n kyverno --all --replicas=0Webhooks timeout, failurePolicy takes effect
Restore after fixkubectl scale deploy -n kyverno --all --replicas=1Re-enables policy enforcement

WARNING: Both options disable all Kyverno policy enforcement. Recommend these only when the cluster is operationally blocked.


Policy Testing

# Dry-run a resource against admission policies
kubectl apply -f resource.yaml --dry-run=server

# Use Kyverno CLI for offline testing
kyverno apply policy.yaml --resource resource.yaml

# Test all policies against a resource
kyverno apply /path/to/policies/ --resource resource.yaml

# Generate policy report for existing resources
kyverno apply policy.yaml --cluster

MCP Tools Available

When the appropriate MCP servers are connected, prefer these over raw kubectl where available:

  • mcp__flux-operator-mcp__get_kubernetes_resources - Query ClusterPolicies, Policies, PolicyReports, webhooks
  • mcp__flux-operator-mcp__get_kubernetes_logs - Retrieve Kyverno admission and background controller logs
  • mcp__flux-operator-mcp__get_kubernetes_metrics - Check Kyverno resource consumption

Common Mistakes

MistakeWhy It FailsInstead
Enforcing policies without testing in Audit firstBlocks legitimate workloads in productionDeploy with Audit, review PolicyReports, then switch to Enforce
Not excluding system namespacesBlocks kube-system, kyverno, or cert-manager operationsAlways exclude kube-system, kyverno, and infrastructure namespaces
Broad match with no excludeEvery resource in the cluster matchesUse specific kinds, namespaces, or selector in match
Debugging by reading policy YAML alonePolicy may be correct but match criteria wrongUse --dry-run=server or Kyverno CLI to test actual behaviour
Deleting webhooks to "fix" issuesKyverno recreates them on restart; root cause persistsDiagnose the actual policy or controller issue first
Not checking both validate AND mutate webhooksMutation happens before validation; mutation may cause validation failuresCheck the mutating webhook first, then validating

Behavioural Guidelines

  1. Identify the policy first — The admission error message contains the policy and rule name. Start there.
  2. Check Audit vs Enforce — A policy in Audit mode allows resources through. Verify the enforcement mode before deeper debugging.
  3. Exclude system namespaces — Always verify that kube-system, kyverno, and critical infrastructure namespaces are excluded.
  4. Test with dry-run — Use kubectl apply --dry-run=server to test without persisting.
  5. Check webhook health before policy logic — If the webhook is down with Fail policy, everything is blocked regardless of policy content.
  6. Never weaken policies without understanding why — Recommend switching to Ignore failurePolicy or deleting webhooks only as an emergency measure, not a fix.
  7. Check mutation before validation — Mutations are applied first. A missing mutation can cause a subsequent validation failure.
  8. Review PolicyReports — For Audit mode policies, PolicyReports contain the violation details.
  9. Report what you find, recommend what to change — This skill is diagnostic-only. Present findings and recommend commands for the user to execute.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.