80+ Helm commands for install, upgrade, rollback, values, templating, repositories, and debugging. Includes a Go Template Quick Reference. Verified against official Helm docs.
Everything runs in your browser. No commands or data are sent to any server.
5 essential commands to get you started. The full reference is right below.
helm install my-release bitnami/nginx Install a Helm chart into your Kubernetes cluster with a release name you choose.
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.
helm list List all Helm releases installed in the current namespace.
helm rollback my-release 1 Roll back a release to a previous revision number when an upgrade causes problems.
helm uninstall my-release Remove a Helm release and all Kubernetes resources it created.
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.
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.
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.
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.
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.
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.
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.
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.
helm show chart bitnami/nginx ↓ Click command to explain
When to use this
Display the chart metadata including version, description, and dependencies.
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.
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.
helm dependency list ./my-chart ↓ Click command to explain
When to use this
List all dependencies for a chart and their current download status.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
helm repo list ↓ Click command to explain
When to use this
List all configured chart repositories and their URLs.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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.
helm upgrade my-release bitnami/nginx --debug ↓ Click command to explain
When to use this
Upgrade with full debug output to diagnose upgrade failures.
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.
helm plugin list ↓ Click command to explain
When to use this
List all installed Helm plugins.
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.
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.
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.
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.
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.
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.
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.
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.
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.
helm plugin install https://github.com/helm/helm-2to3 ↓ Click command to explain
When to use this
Install a Helm plugin from a URL.
helm plugin update 2to3 ↓ Click command to explain
When to use this
Update an installed plugin to its latest version.
helm plugin uninstall 2to3 ↓ Click command to explain
When to use this
Remove an installed plugin.
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.
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.
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 }} 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 }} 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 }} 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 }} 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 }} 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 }} 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.
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.