skip to content

In Helm, is a release name unique per cluster or per namespace, and what follows from that?

level: middleimportance: should knowfreq 58%

answer

  1. Where does Helm keep track of a release
  2. Same name in two namespaces
  3. Two names, one chart, one namespace
  4. The chart decides whether object names collide
  5. `.Release.Name`, fullname helper, 53 characters

basics

~20 s

A Helm release name must be unique within its namespace, not across the cluster. The same name in two namespaces is two independent releases, and one chart can be installed twice in one namespace under two different names.

solid answer

~40 s

Helm scopes a release to a namespace, so uniqueness is per namespace: `transcoder` in `media-eu` and `transcoder` in `media-us` are two unrelated releases, each with its own revision history, and `helm list` shows only the current namespace unless you pass `-A`. Installing a chart a second time in the *same* namespace therefore just needs a second release name — but only works if the chart derives its object names from `.Release.Name`, which the `fullname` helper scaffolded by `helm create` does. A chart with a hardcoded `metadata.name` cannot be installed twice side by side: the second release renders the same object, which already exists and belongs to the first release. Release names are lowercase DNS labels capped at 53 characters, and they become the prefix of object names bounded at 63.

code

bash · 10 lines
bash
# Two independent releases that happen to share a name
helm upgrade --install transcoder ./transcoder-operator -n media-eu
helm upgrade --install transcoder ./transcoder-operator -n media-us

# Two releases of one chart in one namespace
helm upgrade --install transcoder-audio ./transcoder-operator -n media-eu
helm upgrade --install transcoder-video ./transcoder-operator -n media-eu

helm list -n media-eu     # only this namespace
helm list -A              # every namespace

go deeper

for a junior

Remember that a release lives in a namespace and that helm list shows only the current one; -A widens it. Be able to say that the same release name in two namespaces means two separate releases.

for a middle

Explain why the scope is the namespace — that is where Helm keeps the release record — and that installing a chart twice in one namespace needs both a second release name and a chart whose object names come from .Release.Name.

for a senior

Show that you have debugged the collision: hardcoded metadata.name values, untemplated ServiceAccounts, selector labels missing the instance label, and release names long enough that the truncated object names stop being distinct.

for a principal

Own the convention across the estate: whether tenants get a namespace each or a release name each, how names are generated so they stay under the length limits, and what your chart review requires before a chart is allowed to claim it is multi-instance.

## The scope of a name A Helm release is a namespaced thing. Helm keeps its record of the release in the namespace the release was installed into, and every command that reads or writes a release resolves the namespace first — from `-n`/`--namespace` if given, otherwise from the `HELM_NAMESPACE` environment variable, otherwise from the current kube context's namespace, and failing all of that, `default`. Uniqueness follows the record: a release name has to be unique **within its namespace**, and says nothing about any other namespace in the cluster. That has three consequences worth having straight in an interview. **Two namespaces can hold the same name.** Installing `transcoder` in `media-eu` and `transcoder` in `media-us` gives you two entirely independent releases. Each has its own revision counter, its own stored values, its own history. Upgrading one has no effect on the other, and rolling one back does not touch the other. This is the ordinary way to run per-environment or per-tenant copies of one chart, and it is why almost every Helm command is quietly namespace-scoped: `helm list` shows the current namespace only, `helm list -A` (`--all-namespaces`) shows the whole cluster, and `helm status`/`helm history`/`helm upgrade` without `-n` will happily report that a release you can plainly see does not exist — because you are looking in the wrong namespace. **One namespace can hold two releases of one chart.** Nothing stops you installing the same chart twice under `transcoder-audio` and `transcoder-video` in one namespace. Helm has no objection: two names, two records. But Helm only guarantees the *release names* do not collide. It makes no promise at all about the object names the chart renders. **A release name that is already in use is refused.** `helm install` with a name that exists in the namespace fails rather than adopting or overwriting the existing release. That is the check that makes `helm upgrade --install` the pipeline-friendly command; it is also a cheap guard when you deliberately want a run to fail rather than write to a release it did not create. ## The part Helm does not do for you: object names Whether a chart can be installed twice in a namespace is a property of the *chart*, not of Helm. A well-written chart derives every object name from the release name. The helper that `helm create` scaffolds does exactly this — it composes the release name with the chart name and truncates the result to 63 characters, the Kubernetes limit for a name of that form: ```yaml metadata: name: {{ include "transcoder.fullname" . }} labels: app.kubernetes.io/instance: {{ .Release.Name }} ``` Install that chart as `transcoder-audio` and again as `transcoder-video` and you get two disjoint sets of Deployments, Services and ConfigMaps that can sit in one namespace without noticing each other. A chart whose author wrote `metadata.name: transcoder-api` literally is a different story. The second release renders an object with a name that already exists in the namespace and belongs to the first release, and the install fails. Helm will not silently rename it and will not silently share it. The same trap appears in the small details people forget to template: a ServiceAccount, a ConfigMap of shared configuration, a Secret name pinned so a sidecar can find it, an Ingress host. A 240-line values file for an operator chart usually has one or two of these hiding in it, and the way you find them is to install the chart twice into a scratch namespace rather than to read the templates. The selector labels matter too. If two releases render Deployments whose pod selectors match each other's pods, the two controllers fight over the same pods even though the object names differ. Including `app.kubernetes.io/instance: {{ .Release.Name }}` in the selector is what keeps the two copies apart, which is why the generated chart puts it there. ## Name rules, and why they bite A release name must be a lowercase RFC 1123 name — letters, digits and dashes — and Helm caps it at 53 characters. That ceiling exists because the release name is normally a *prefix* of the object names a chart renders, and those have their own limits; the generated `fullname` helper truncates at 63 for that reason. Long, machine-generated release names (a branch name plus a commit prefix, say) are where this shows up: the release installs, but two ephemeral environments whose names differ only after character 63 end up rendering the same object name and colliding. ## Where the per-namespace rule stops The one thing this rule does not cover is objects that are not namespaced at all. Two releases of a chart that renders a ClusterRole, a CustomResourceDefinition or a webhook configuration will collide on those regardless of which namespaces the releases live in, because there is only one cluster-wide name for each. Per-namespace release naming buys you isolation exactly as far as the objects being namespaced.

  • You can see a release in the cluster but `helm history` says it does not exist. What is the first thing you check?
    The namespace. Helm resolves it from `-n`, then `HELM_NAMESPACE`, then the current kube context, then `default`, and every release command is scoped to whatever that resolves to. A release installed into `media-eu` is invisible to a `helm history` run against `default`. Confirm with `helm list -A`, which lists releases across all namespaces, then re-run with the right `-n`.
  • What in a chart most often prevents a second release of it from installing alongside the first in one namespace?
    A hardcoded object name. Any `metadata.name` written as a literal — a ServiceAccount, a shared ConfigMap, an Ingress — renders identically for both releases, so the second install hits an object that already exists and belongs to the other release. Selector labels are the subtler version: if the pod selectors match each other's pods, the two copies fight even when the object names differ.

saying these in an interview costs you the question

  • Says release names must be unique across the whole cluster
  • Thinks `helm list` shows every namespace by default
  • Assumes Helm renames colliding objects for the second release
  • Believes two same-named releases share one revision history
  • Claims any chart can be installed twice in a namespace

context