KUBERNETES Updated 2026-07-08 81+ commands Verified against official docs

Helm Cheat Sheet

80+ Helm commands for install, upgrade, rollback, values, templating, repositories, and debugging. Includes a Go Template Quick Reference. Verified against official Helm docs.

Ctrl+K

Everything runs in your browser. No commands or data are sent to any server.

New to Helm? Start with these

5 essential commands to get you started. The full reference is right below.

Install a chart as a new release

helm install my-release bitnami/nginx

Install a Helm chart into your Kubernetes cluster with a release name you choose.

Install or upgrade a release idempotently

helm upgrade --install my-release bitnami/nginx

Install a chart if it does not exist or upgrade it if it does. This is the idempotent command used in CI pipelines.

List installed releases

helm list

List all Helm releases installed in the current namespace.

Roll back a release to a previous revision

helm rollback my-release 1

Roll back a release to a previous revision number when an upgrade causes problems.

Uninstall a release

helm uninstall my-release

Remove a Helm release and all Kubernetes resources it created.

81 commands

Install a chart as a new release

Beginner Destructive
helm install my-release bitnami/nginx

↓ Click command to explain

--namespace Installs into a specific namespace
--create-namespace Creates the namespace if it does not exist
--values / -f Uses a custom values file
--set key=value Overrides a single value on the command line
--dry-run Simulates the install without making changes

When to use this

Install a Helm chart into your Kubernetes cluster with a release name you choose.

Gotcha

The release name you choose must be unique within the namespace. If a release with that name already exists, use helm upgrade instead.

Install or upgrade a release idempotently

Beginner Destructive
helm upgrade --install my-release bitnami/nginx

↓ Click command to explain

--atomic Automatically rolls back if the upgrade fails
--wait Waits until all pods are running before returning
--timeout Sets how long to wait
--set key=value Overrides a value
--values / -f Uses a custom values file

When to use this

Install a chart if it does not exist or upgrade it if it does. This is the idempotent command used in CI pipelines.

Gotcha

Always use --atomic in production upgrades so Helm automatically rolls back if the new version fails to deploy. Without --atomic, a failed upgrade leaves the release in a broken pending-upgrade state.

List installed releases

Beginner
helm list

↓ Click command to explain

--all-namespaces / -A Shows releases across all namespaces
--namespace / -n Filters by namespace
--failed Shows only failed releases
--pending Shows only pending releases

When to use this

List all Helm releases installed in the current namespace.

Gotcha

helm list without -A only shows releases in the current namespace set in your kubectl context. If you cannot find your release, add -A to search all namespaces.

Roll back a release to a previous revision

Beginner Destructive
helm rollback my-release 1

↓ Click command to explain

--wait Waits until all pods are running after rollback
--timeout Sets how long to wait
--dry-run Simulates the rollback without making changes

When to use this

Roll back a release to a previous revision number when an upgrade causes problems.

Gotcha

Run helm history my-release to see all revision numbers before running rollback. Revision 0 means the previous revision.

Uninstall a release

Intermediate Destructive
helm uninstall my-release

↓ Click command to explain

--keep-history Keeps the release history in Kubernetes secrets after uninstalling
--dry-run Simulates without making changes

When to use this

Remove a Helm release and all Kubernetes resources it created.

Gotcha

Uninstall deletes all resources created by the chart including PersistentVolumeClaims by default. If you want to keep your data, add --keep-history and handle PVC deletion manually.

Create a new chart scaffold

Beginner
helm create my-chart

↓ Click command to explain

When to use this

Create a new Helm chart with the standard directory structure and example templates.

Gotcha

The generated chart includes example deployment, service, and ingress templates that you modify for your application. Delete the templates you do not need rather than leaving empty files.

Package a chart into a .tgz archive

Intermediate
helm package ./my-chart

↓ Click command to explain

--destination Sets the output directory for the packaged chart
--version Overrides the chart version

When to use this

Package a chart directory into a .tgz archive for distribution or uploading to a chart repository.

Show a chart's default values

Beginner
helm show values bitnami/nginx

↓ Click command to explain

When to use this

Display all the default values for a chart so you know what you can override in your values file.

Gotcha

Pipe the output to a file with helm show values bitnami/nginx > values.yaml to create a starting point for your custom values file.

Show a chart's metadata

Beginner
helm show chart bitnami/nginx

↓ Click command to explain

When to use this

Display the chart metadata including version, description, and dependencies.

Show a chart's README

Beginner
helm show readme bitnami/nginx

↓ Click command to explain

When to use this

Display the README for a chart to understand how to configure and use it.

Update chart dependencies

Intermediate
helm dependency update ./my-chart

↓ Click command to explain

When to use this

Download and update all chart dependencies listed in Chart.yaml before packaging or installing.

Gotcha

Run this before helm install or helm package when working with a chart that has dependencies. Forgetting this step causes missing subchart errors.

List chart dependencies

Beginner
helm dependency list ./my-chart

↓ Click command to explain

When to use this

List all dependencies for a chart and their current download status.

Download a chart locally

Intermediate
helm pull bitnami/nginx --untar

↓ Click command to explain

--untar Extracts the chart after downloading
--version Downloads a specific chart version
--destination Sets where to save the chart

When to use this

Download a chart from a repository to inspect or modify it locally.

Simulate an install without applying it

Beginner
helm install my-release bitnami/nginx --dry-run

↓ Click command to explain

When to use this

Simulate an install and see the rendered Kubernetes manifests without applying anything to the cluster.

Gotcha

--dry-run requires a connection to the cluster to validate the manifests. Use helm template instead for a fully offline render.

Upgrade an existing release

Intermediate Destructive
helm upgrade my-release bitnami/nginx

↓ Click command to explain

--atomic Rolls back automatically on failure
--wait Waits for pods to be ready
--timeout Sets wait duration
--force Forces resource updates by deleting and recreating
--cleanup-on-fail Cleans up new resources if upgrade fails

When to use this

Upgrade an existing release to a new chart version or with updated values.

Gotcha

Without --atomic, a failed upgrade leaves the release in pending-upgrade state which blocks future upgrades until you manually roll back.

Upgrade with a single value override

Intermediate Destructive
helm upgrade my-release bitnami/nginx --set image.tag=1.25

↓ Click command to explain

When to use this

Upgrade a release and override a single value without a full values file.

Gotcha

Values set with --set take precedence over values files but are not stored anywhere persistent. Document overrides in a values file for reproducibility.

Roll back to the previous revision

Beginner Destructive
helm rollback my-release 0

↓ Click command to explain

When to use this

Roll back to the immediately previous revision using revision number 0 as shorthand.

Show a release's revision history

Beginner
helm history my-release

↓ Click command to explain

--max Limits the number of revisions shown

When to use this

Show the complete revision history of a release including status, chart version, and description for each revision.

Gotcha

Revision numbers in history are what you use with helm rollback. If history shows no entries, the release may have been installed with --no-hooks or history may have been purged.

Install and wait for resources to be ready

Intermediate Destructive
helm install my-release bitnami/nginx --wait --timeout 5m

↓ Click command to explain

When to use this

Install a chart and wait until all pods, PVCs, and services are in a ready state before returning success.

Gotcha

Without --wait, helm returns immediately after submitting the manifests to Kubernetes even if pods fail to start. Add --wait in CI so a failed deploy is caught at install time.

Upgrade and reset values to chart defaults

Advanced Destructive
helm upgrade my-release bitnami/nginx --reset-values

↓ Click command to explain

When to use this

Upgrade a release and reset all values back to the chart defaults, discarding any custom values from previous installs.

Gotcha

This discards all your custom configuration. Use --reuse-values instead if you want to keep existing overrides and only change specific values.

Upgrade while keeping previous values

Intermediate Destructive
helm upgrade my-release bitnami/nginx --reuse-values --set image.tag=1.25

↓ Click command to explain

When to use this

Upgrade a release while keeping all the values from the previous install and only overriding specific ones.

Install with an auto-generated release name

Intermediate Destructive
helm install --generate-name bitnami/nginx

↓ Click command to explain

When to use this

Install a chart with an automatically generated release name, useful in CI environments where you want unique release names.

Uninstall while keeping release history

Intermediate Destructive
helm uninstall my-release --keep-history

↓ Click command to explain

When to use this

Remove all resources created by a release while keeping the release history so you can roll back if needed.

Install a specific chart version

Intermediate Destructive
helm install my-release bitnami/nginx --version 15.5.0

↓ Click command to explain

When to use this

Install a specific version of a chart instead of the latest, important for reproducible deployments.

Gotcha

Without --version, helm installs the latest chart version available in the repo index, which can silently introduce breaking changes between environments if not pinned.

Install or upgrade with a pinned version and values

Advanced Destructive
helm upgrade --install my-release bitnami/nginx --version 15.5.0 -f values.yaml

↓ Click command to explain

When to use this

Combine the idempotent upgrade or install pattern with a pinned chart version and custom values, the standard production CI deploy command.

Preview a rollback before running it

Intermediate
helm rollback my-release 2 --dry-run

↓ Click command to explain

When to use this

Preview what a rollback to a specific revision would change before actually performing it.

Preview an uninstall before running it

Intermediate
helm uninstall my-release --dry-run

↓ Click command to explain

When to use this

Preview which resources would be deleted by an uninstall without actually removing anything.

Force resource replacement during upgrade

Advanced Destructive
helm upgrade my-release bitnami/nginx --force

↓ Click command to explain

When to use this

Force resource updates through a replace strategy, deleting and recreating resources that cannot be updated in place.

Gotcha

--force can cause brief downtime since it deletes resources before recreating them. Avoid using it as a routine upgrade flag and reserve it for resources stuck in an unpatchable state.

Extend the install wait timeout

Intermediate Destructive
helm install my-release bitnami/nginx --timeout 10m

↓ Click command to explain

When to use this

Extend how long Helm waits for resources to become ready before considering the install failed, useful for charts with slow-starting dependencies.

Limit the number of retained revisions

Intermediate Destructive
helm upgrade my-release bitnami/nginx --history-max 10

↓ Click command to explain

When to use this

Limit how many old revisions Helm retains for a release, keeping only the most recent ones to reduce clutter in the release secrets.

Install without running lifecycle hooks

Advanced Destructive
helm install my-release bitnami/nginx --no-hooks

↓ Click command to explain

When to use this

Install a chart without running any of its lifecycle hooks, useful when a hook is failing and you need to get the base resources deployed.

Gotcha

Skipping hooks can leave a chart partially configured since many charts rely on hooks for jobs like database migrations. Only use this as a temporary debugging measure.

Uninstall without running lifecycle hooks

Advanced Destructive
helm uninstall my-release --no-hooks

↓ Click command to explain

When to use this

Uninstall a release without running any pre-delete or post-delete hooks.

Render chart templates locally

Intermediate
helm template my-release bitnami/nginx

↓ Click command to explain

-f / --values Uses a custom values file
--set Overrides a value
--show-only Renders only a specific template file
--namespace Sets the namespace in rendered output

When to use this

Render chart templates locally to see the exact Kubernetes YAML that would be applied without connecting to the cluster.

Gotcha

helm template does not validate against a live cluster so it can render manifests that are invalid in your specific cluster. Use helm install --dry-run for server-side validation.

Render templates to a file

Intermediate
helm template my-release ./my-chart -f values.yaml > rendered.yaml

↓ Click command to explain

When to use this

Render all templates to a single YAML file for review or for applying with kubectl apply -f.

Lint a chart for errors

Beginner
helm lint ./my-chart

↓ Click command to explain

--strict Treats warnings as errors
--values / -f Uses a custom values file for linting

When to use this

Check a chart for common errors and best practice violations before packaging or installing.

Gotcha

helm lint catches many template issues but not all. Always follow with helm template to visually inspect the rendered output.

Show the values used for a release

Beginner
helm get values my-release

↓ Click command to explain

--all Shows computed values including defaults
--revision Shows values from a specific revision
--output yaml / json Changes the output format

When to use this

See the custom values that were used to install or upgrade a release.

Gotcha

helm get values without --all only shows values that were explicitly overridden. Add --all to see the complete computed values including chart defaults.

Show the manifests applied for a release

Intermediate
helm get manifest my-release

↓ Click command to explain

When to use this

Show the Kubernetes manifests that were applied to the cluster for a release.

Show everything about a release

Intermediate
helm get all my-release

↓ Click command to explain

When to use this

Show all information about a release including values, manifests, hooks, and notes.

Install with a custom values file

Intermediate Destructive
helm install my-release bitnami/nginx -f custom-values.yaml

↓ Click command to explain

When to use this

Install a chart using custom values from a file to override the chart defaults.

Gotcha

Multiple -f flags are supported and values are merged left to right with later files taking precedence.

Upgrade with a custom values file

Intermediate Destructive
helm upgrade my-release bitnami/nginx -f custom-values.yaml

↓ Click command to explain

When to use this

Upgrade a release with values from a file.

Gotcha

If you switch from --set overrides to a values file during an upgrade, use --reset-values first or the old --set values may persist.

Export default values as a starting point

Intermediate
helm show values bitnami/nginx > default-values.yaml

↓ Click command to explain

When to use this

Save the chart default values to a file as a starting point for building your custom values file.

Show chart metadata, values, and README together

Beginner
helm show all bitnami/nginx

↓ Click command to explain

When to use this

Display the chart metadata, default values, and README all together in a single command output.

Render a single template file

Intermediate
helm template my-release ./my-chart --show-only templates/deployment.yaml

↓ Click command to explain

When to use this

Render only one specific template file instead of the entire chart, useful when debugging a single resource.

Force a value to be treated as a string

Advanced Destructive
helm install my-release bitnami/nginx --set-string image.tag=1.25

↓ Click command to explain

When to use this

Force a --set value to be treated as a string instead of letting Helm infer its type, important for values like version tags that look numeric.

Gotcha

Without --set-string, a value like image.tag=1.25 that looks like a number can be parsed as a numeric type instead of a string, which breaks templates that expect a string.

Set a value from a file's contents

Advanced Destructive
helm install my-release ./my-chart --set-file config=./app.conf

↓ Click command to explain

When to use this

Set a value to the contents of a file instead of typing it inline, useful for multi-line configuration blocks or certificates.

Add a chart repository

Beginner
helm repo add bitnami https://charts.bitnami.com/bitnami

↓ Click command to explain

When to use this

Add a Helm chart repository so you can install charts from it.

Gotcha

You must run helm repo update after adding a new repository before you can install charts from it.

Refresh chart repository indexes

Beginner
helm repo update

↓ Click command to explain

When to use this

Fetch the latest list of charts from all configured repositories.

Gotcha

Run this regularly or before installing charts to ensure you are seeing the latest available versions.

List configured repositories

Beginner
helm repo list

↓ Click command to explain

When to use this

List all configured chart repositories and their URLs.

Remove a chart repository

Intermediate Destructive
helm repo remove bitnami

↓ Click command to explain

When to use this

Remove a chart repository from your local configuration.

Gotcha

Removing a repository does not uninstall any charts already installed from it.

Search configured repositories

Beginner
helm search repo nginx

↓ Click command to explain

--versions Shows all available chart versions
--regexp Enables regex matching in the search term

When to use this

Search your configured repositories for charts matching a keyword.

Gotcha

helm search repo only searches repositories you have added with helm repo add. Use helm search hub to search the public Artifact Hub.

Search the public Artifact Hub

Beginner
helm search hub nginx

↓ Click command to explain

When to use this

Search the public Artifact Hub for publicly available Helm charts.

Gotcha

Charts found on the hub may be from any publisher. Check the publisher verification status before using a chart in production.

Authenticate to an OCI registry

Intermediate
helm registry login registry.example.com --username myuser --password mypassword

↓ Click command to explain

When to use this

Authenticate to an OCI registry to push or pull charts stored as OCI artifacts.

Gotcha

OCI registry support was added in Helm 3.8 as stable. If you are on an older version, use a traditional chart repository instead.

Push a packaged chart to an OCI registry

Intermediate
helm push my-chart-1.0.0.tgz oci://registry.example.com/charts

↓ Click command to explain

When to use this

Push a packaged chart to an OCI registry.

Generate a repository index file

Advanced
helm repo index ./charts-repo

↓ Click command to explain

When to use this

Generate an index.yaml file for a directory of packaged charts, turning it into a valid Helm chart repository.

Download a chart by repository URL

Intermediate
helm pull nginx --repo https://charts.bitnami.com/bitnami --untar

↓ Click command to explain

When to use this

Download a chart directly by repository URL without first running helm repo add, useful for one-off downloads.

Check a release's current status

Beginner
helm status my-release

↓ Click command to explain

--show-resources Shows all Kubernetes resources created by the release
--revision Shows the status of a specific revision

When to use this

Check the current status of a Helm release including whether it is deployed, failed, or pending.

Gotcha

helm status shows the release status from Helm's perspective. Use kubectl get pods to see the actual pod status.

List failed releases

Beginner
helm list --failed

↓ Click command to explain

When to use this

List only releases that are in a failed state so you can quickly identify broken deployments.

List releases stuck in a pending state

Intermediate
helm list --pending

↓ Click command to explain

When to use this

List releases stuck in pending-install or pending-upgrade state which indicates a previous operation did not complete cleanly.

Gotcha

A release stuck in pending-upgrade blocks all future upgrades. Fix it by running helm rollback my-release to a known good revision.

Show a release's NOTES.txt output

Beginner
helm get notes my-release

↓ Click command to explain

When to use this

Display the NOTES.txt output from a chart which usually contains instructions for accessing the deployed application.

Show a limited number of recent revisions

Intermediate
helm history my-release --max 5

↓ Click command to explain

When to use this

Show the last 5 revisions of a release to understand recent changes.

List only healthy deployed releases

Beginner
helm list --deployed

↓ Click command to explain

When to use this

List only releases that are currently in a healthy deployed state, filtering out failed or pending ones.

Lint a chart with strict validation

Intermediate
helm lint ./my-chart --strict

↓ Click command to explain

When to use this

Lint a chart and treat all warnings as errors for strict validation in CI pipelines.

Render templates with debug output

Intermediate
helm template my-release ./my-chart --debug

↓ Click command to explain

When to use this

Render templates with debug output showing which template files are being processed and any errors in detail.

Simulate an install with debug output

Advanced
helm install my-release bitnami/nginx --debug --dry-run

↓ Click command to explain

When to use this

Simulate an install with full debug output showing the rendered manifests and all Helm operations.

Upgrade with debug output

Advanced Destructive
helm upgrade my-release bitnami/nginx --debug

↓ Click command to explain

When to use this

Upgrade with full debug output to diagnose upgrade failures.

List a release's hook manifests

Advanced
helm get hooks my-release

↓ Click command to explain

When to use this

List all hook manifests associated with a release to debug pre-install or post-install hook failures.

Gotcha

Hook failures are a common cause of releases being stuck in pending-install state. Inspect the hook pod logs with kubectl logs after identifying the hook pod name.

List installed Helm plugins

Beginner
helm plugin list

↓ Click command to explain

When to use this

List all installed Helm plugins.

Show a release's status with full resource list

Intermediate
helm status my-release --show-resources

↓ Click command to explain

When to use this

Show the full status of a release along with every Kubernetes resource it created, useful for confirming exactly what got deployed.

View the manifest from a past revision

Advanced
helm get manifest my-release --revision 2

↓ Click command to explain

When to use this

View the exact manifest that was applied for a specific past revision, useful for comparing what changed between two failed deployments.

Preview an upgrade diff against the live cluster

Advanced
helm diff upgrade my-release bitnami/nginx -f values.yaml

↓ Click command to explain

When to use this

Preview exactly what an upgrade would change in the live cluster before running it for real, using the popular helm-diff plugin.

Gotcha

This requires installing the helm-diff plugin first with helm plugin install https://github.com/databus23/helm-diff. It is not part of the core Helm CLI.

Render and validate templates against the cluster API

Advanced
helm template my-release ./my-chart --validate

↓ Click command to explain

When to use this

Render templates and validate them against the Kubernetes API schema of the connected cluster, catching invalid API versions or fields.

Gotcha

--validate requires a connection to a live cluster to check the resources against, unlike a plain offline helm template render.

Show NOTES.txt output from subcharts

Advanced Destructive
helm install my-release ./my-chart --render-subchart-notes

↓ Click command to explain

When to use this

Display the NOTES.txt output from subcharts in addition to the parent chart, useful when debugging which chart in a dependency tree is producing confusing output.

Confirm you are running Helm 3

Beginner
helm version

↓ Click command to explain

When to use this

Confirm you are running Helm 3, which does not require Tiller, uses namespaced releases by default, and uses OCI registries.

Gotcha

Helm 2 required a server-side component called Tiller with cluster-admin permissions, which was a major security concern. Helm 3 removed Tiller entirely and stores release data as Kubernetes secrets in the release namespace.

View Helm 3's release state secrets

Advanced
kubectl get secrets -n my-namespace -l owner=helm

↓ Click command to explain

When to use this

View the Kubernetes secrets that Helm 3 uses to store release state in the release namespace.

Migrate a Helm 2 release to Helm 3

Advanced
helm 2to3 convert my-release

↓ Click command to explain

When to use this

Migrate a Helm 2 release to Helm 3 format using the 2to3 plugin.

Gotcha

Install the plugin first with helm plugin install https://github.com/helm/helm-2to3.

Remove leftover Helm 2 data after migration

Advanced Destructive
helm 2to3 cleanup

↓ Click command to explain

When to use this

Remove all Helm 2 data including Tiller's ConfigMaps after confirming every release has been successfully migrated to Helm 3.

Gotcha

Only run cleanup after verifying every Helm 2 release was migrated and is working correctly in Helm 3, since cleanup permanently deletes the Helm 2 release data you would need to roll back.

Install a Helm plugin

Intermediate
helm plugin install https://github.com/helm/helm-2to3

↓ Click command to explain

When to use this

Install a Helm plugin from a URL.

Update an installed plugin

Intermediate
helm plugin update 2to3

↓ Click command to explain

When to use this

Update an installed plugin to its latest version.

Remove an installed plugin

Intermediate Destructive
helm plugin uninstall 2to3

↓ Click command to explain

When to use this

Remove an installed plugin.

Show Helm environment variables

Beginner
helm env

↓ Click command to explain

When to use this

Show all Helm environment variables and their current values including plugin directory, data directory, and cache directory.

Install a pinned plugin version

Advanced
helm plugin install https://github.com/databus23/helm-diff --version v3.9.0

↓ Click command to explain

When to use this

Install a specific pinned version of a plugin instead of the latest, useful for reproducible CI environments.

Reference Tools

The most confusing Helm templating patterns and the exact errors they fix. These are the issues that generate the most Stack Overflow questions and Reddit complaints about Helm.

Whitespace Control

{{- expression -}}

The hyphen trims whitespace and newlines on that side of the expression. Use {{- to trim whitespace before the tag and -}} to trim whitespace after it.

{{- if .Values.enabled }} enabled: true {{- end }}
Fixes: Unexpected blank lines or extra indentation in rendered YAML

Gotcha

Missing a hyphen on one side only trims that side. Forgetting both hyphens leaves extra blank lines that can break YAML parsing in strict validators.

nindent vs indent

{{ .Values.config | nindent 4 }}

nindent adds a newline before the indented content. indent does not add a newline. Use nindent when embedding a multi-line value inside a YAML block.

data: config: | {{ .Values.config | nindent 4 }}
Fixes: YAML indentation errors when embedding multi-line values

Gotcha

Using indent instead of nindent when the value starts on the same line as the key causes the first line to be unindented relative to the rest producing invalid YAML.

toYaml for complex values

{{ toYaml .Values.resources | nindent 12 }}

toYaml converts a Helm values object into a YAML string. Always pipe it through nindent to get correct indentation.

resources: {{ toYaml .Values.resources | nindent 4 }}
Fixes: nil pointer evaluating interface {} when rendering nested objects

Gotcha

Forgetting nindent after toYaml produces a single-line YAML string with no indentation which is invalid in nested contexts.

required for mandatory values

{{ required "image.tag is required" .Values.image.tag }}

required fails the helm install or upgrade with a clear error message if the specified value is empty or not set. Use this to enforce required values instead of letting them fail silently.

image: tag: {{ required "image.tag must be set" .Values.image.tag }}
Fixes: Silent deployment failures when required values are missing

Gotcha

Without required a missing value renders as an empty string which may cause the pod to fail at runtime with a confusing error rather than failing at install time with a clear message.

default for fallback values

{{ .Values.replicas | default 1 }}

default provides a fallback value when the specified value is empty, nil, or not set in values.yaml.

replicas: {{ .Values.replicas | default 1 }}
Fixes: nil pointer evaluating interface {} when a value is not set

Gotcha

default only activates when the value is empty or nil. If the user explicitly sets a value to false or 0 those are treated as set values and default does not activate.

Nil Pointer Error

{{ if .Values.section }}{{ .Values.section.key }}{{ end }}

Always check if a parent key exists before accessing a child key. Accessing .Values.section.key when section is not defined causes a nil pointer error.

{{- if .Values.ingress }} host: {{ .Values.ingress.host }} {{- end }}
Fixes: nil pointer evaluating interface {}.key

Gotcha

This is the single most common Helm template error. Always wrap nested value access in an if block that checks the parent key first.

Frequently Asked Questions

Helm is the package manager for Kubernetes, the tool that lets you define, install, and upgrade even the most complex Kubernetes application as a single unit instead of hand writing and applying a dozen separate YAML files. A Helm chart bundles all the Kubernetes manifests an application needs, such as Deployments, Services, ConfigMaps, and Ingress rules, into one templated package that can be parameterized with a values file and reused across environments. Instead of maintaining slightly different copies of the same YAML for dev, staging, and production, you maintain one chart and swap out the values file, which is the same relationship a package manager like apt or npm has to raw binaries and source code.

The reason Helm shows up constantly in Kubernetes workflows is that most real applications are not a single Deployment. A typical service might need a Deployment, a Service, an Ingress, a ConfigMap, a Secret, and a HorizontalPodAutoscaler, and keeping all of those in sync by hand across every environment and every release becomes unmanageable quickly. helm install and helm upgrade let a team ship that entire bundle as one versioned, reviewable unit, and because Helm tracks every release as a numbered revision, rolling back a bad deploy is a single helm rollback command instead of manually reconstructing the previous state of five different YAML files. This is exactly why helm upgrade --install has become the default deploy step in most Kubernetes CI pipelines.

The two core concepts that make Helm click are charts and releases. A chart is the packaged template, the reusable blueprint that defines what an application looks like and which values can be customized. A release is a specific installed instance of a chart in a cluster, identified by a release name and tracked as a sequence of numbered revisions in Kubernetes secrets. The same chart can be installed multiple times under different release names, for example running two separate instances of the same nginx chart side by side, and each release keeps its own independent history so upgrading or rolling back one release never touches the other.

Three mistakes account for most of the frustration engineers hit when learning Helm. The first is accessing a nested value like .Values.ingress.host without first checking that .Values.ingress itself is defined, which produces the notorious nil pointer evaluating interface error the moment a user omits that section from their values file. The second is using indent instead of nindent when embedding a multi-line block inside a YAML template, which leaves the first line of the block unindented and produces invalid YAML that only fails once it reaches the cluster. The third is running helm upgrade without --atomic in production, so a failing upgrade leaves the release stuck in a pending-upgrade state that silently blocks every future upgrade until someone notices and runs a manual rollback.