Debugging Templates Without Touching the Cluster

helm template, --dry-run, --debug and lint let you see exactly what Helm would apply and catch mistakes before Kubernetes ever sees them.

The single biggest jump in Helm productivity is learning to render locally instead of installing and squinting at errors. Ninety percent of chart bugs are visible in the rendered YAML — you just have to look at it.

Your three-command debugging loop

  • helm template renders the whole chart to stdout using only your local machine. No cluster, no release. This is your fastest feedback loop — pipe it to less or into kubectl apply --dry-run=server -f - for real API validation.
  • helm install --dry-run --debug does the same but talks to the cluster, so .Capabilities and lookup reflect the real target, and you see the computed values and manifest together.
  • helm lint catches structural problems — a malformed Chart.yaml, an undefined value, invalid YAML — before you even render.

Two flags that save real time

--show-only templates/deployment.yaml narrows helm template to a single file when a chart renders dozens. And when a value refuses to appear, --set a fake value plus helm template ... | grep confirms in seconds whether the template or the value is at fault.

When an install fails with a YAML parse error, do not guess. Run helm template and read the line it complains about — nine times out of ten it is a missing nindent or a value that rendered empty.

Example

Example Β· bash
# Render the whole chart locally -- fastest possible feedback
helm template my-web ./mychart -f values-prod.yaml

# Just one resource, with the values you would actually ship
helm template my-web ./mychart --show-only templates/deployment.yaml \
  --set image.tag=1.27

# Render against the real cluster (lookup + Capabilities work here)
helm install my-web ./mychart --dry-run --debug -n web

# Validate structure before rendering, and validate output against the API
helm lint ./mychart
helm template my-web ./mychart | kubectl apply --dry-run=server -f -

When to use it

  • A developer runs helm template --dry-run --debug locally to see the final rendered YAML and catch a missing quote before the manifest ever reaches the cluster.
  • A platform engineer pipes helm template output through kubectl apply --dry-run=server to validate the rendered manifests against the live cluster's admission webhooks without creating any resources.
  • A chart author uses helm lint --strict in the CI pipeline to catch deprecated apiVersions and non-standard label conventions before a release is published.

More examples

Render templates locally

Renders all templates to stdout without touching the cluster; --debug also prints the computed values so you can trace where each value came from.

Example Β· bash
helm template my-release ./myapp \
  -f values-prod.yaml \
  --set image.tag=v2.1.0 \
  --debug 2>&1 | less

Validate against live cluster

Pipes rendered YAML through a server-side dry run to catch admission webhook rejections and RBAC issues before real apply.

Example Β· bash
helm template my-release ./myapp \
  -f values-prod.yaml \
  | kubectl apply --dry-run=server -f -

Lint with strict mode

Runs lint in strict mode to promote warnings to errors, and with realistic values to catch conditional branches that only activate in certain configs.

Example Β· bash
helm lint ./myapp --strict
helm lint ./myapp \
  --set image.tag=test \
  -f values-prod.yaml

Discussion

  • Be the first to comment on this lesson.
Debugging Templates Without Touching the Cluster β€” Helm | SoundsCode