🎉 DevOps Interview Prep Bundle is live — 1000+ Q&A across 20 topicsGet it →
All Articles

Kustomize Patch Not Applying — Fix

Your Kustomize overlay patch isn't modifying the base resource. Here's every reason patches silently fail and exactly how to debug and fix each one.

DevOpsBoys3 min read
Share:Tweet

Kustomize patches fail silently — no error, the build succeeds, but the base resource is unchanged. Here's how to find the problem.


Debug First

bash
# Always preview the final output before applying
kubectl kustomize ./overlays/production
 
# Diff against what's running
kubectl kustomize ./overlays/production | kubectl diff -f -
 
# If patch isn't showing up → the patch is silently not matching

Case 1: Strategic Merge Patch — Wrong Target Name

The most common issue. The patch filename or the resource name inside the patch doesn't match the base resource name exactly.

yaml
# base/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app        # ← exact name
 
# overlays/production/patch-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app-prod   # ← WRONG — doesn't match base name, patch is ignored
spec:
  replicas: 3
yaml
# Fix: name must exactly match
metadata:
  name: my-app        # ← must match base exactly

Case 2: JSON6902 Patch — Wrong Target Group/Version/Kind

yaml
# kustomization.yaml
patches:
- target:
    group: apps
    version: v1
    kind: Deployment
    name: my-app
  patch: |-
    - op: replace
      path: /spec/replicas
      value: 3
bash
# Check the exact apiVersion of your resource:
kubectl api-resources | grep Deployment
# group=apps, version=v1 → correct
 
# Common mistake: using "group: apps/v1" instead of separate group + version
# Wrong:
group: apps/v1    # ← this is not valid, group and version are separate fields
# Right:
group: apps
version: v1

Case 3: Path Doesn't Exist in JSON6902 Patch

op: replace on a path that doesn't exist fails silently. Use op: add instead.

yaml
# If the field doesn't exist yet, use add not replace:
- op: add
  path: /spec/template/spec/containers/0/env/-
  value:
    name: ENV_VAR
    value: "production"
 
# Replace only works if the path already exists in the base resource

Case 4: Wrong Resource Listed in kustomization.yaml

yaml
# kustomization.yaml — patch file must be listed
patches:
- path: patch-deployment.yaml   # ← must be listed here
 
resources:
- ../../base
 
# Common mistake: file exists in the directory but isn't referenced in kustomization.yaml
bash
# Verify what Kustomize sees
kubectl kustomize . --load-restrictor=none 2>&1
# Errors about missing files will appear here

Case 5: Namespace Mismatch

If base has no namespace but patch specifies one (or vice versa), the patch won't match.

yaml
# base resource has no namespace:
metadata:
  name: my-app
 
# patch must also have no namespace (or both must match):
metadata:
  name: my-app
  namespace: production   # ← won't match base with no namespace

Fix: add namespace: production to the base, or remove it from the patch, or use kustomization.yaml namespace field:

yaml
# kustomization.yaml
namespace: production   # Applied to all resources uniformly

Verify Patch is Working

bash
# Build and check specific field
kubectl kustomize ./overlays/production | grep -A3 "replicas:"
 
# Build and apply dry-run
kubectl kustomize ./overlays/production | kubectl apply --dry-run=client -f -
 
# Check what kustomize built vs what's running
kubectl kustomize ./overlays/production > /tmp/desired.yaml
kubectl get deployment my-app -o yaml > /tmp/actual.yaml
diff /tmp/desired.yaml /tmp/actual.yaml

Learn GitOps and Kustomize with hands-on labs at KodeKloud.

🔧

Today I Fixed

Short real fixes from production — posted daily

Browse fixes
Newsletter

Stay ahead of the curve

Get the latest DevOps, Kubernetes, AWS, and AI/ML guides delivered straight to your inbox. No spam — just practical engineering content.

Related Articles

Comments