Helm Release Naming Gotchas#
Helm charts derive Kubernetes resource names from the release name, but every chart does it differently. If you assume a consistent pattern, you will get bitten by DNS resolution failures, broken connection strings, and mysterious “service not found” errors.
Bitnami PostgreSQL: Names Are Not What You Expect#
The Bitnami PostgreSQL chart names resources using the release name directly, not {release-name}-postgresql. This catches nearly everyone.
# You deploy like this:
helm upgrade --install dt-postgresql bitnami/postgresql \
--namespace dream-team \
--set auth.database=mattermost \
--set auth.username=mmuser
# You expect these resource names:
# Pod: dt-postgresql-postgresql-0 <-- WRONG
# Service: dt-postgresql-postgresql <-- WRONG
# Actual names:
# Pod: dt-postgresql-0
# Service: dt-postgresqlThis means your application connection string should reference dt-postgresql, not dt-postgresql-postgresql. If you chose release name postgresql, your service is just postgresql – which might collide with other things in your namespace.
Debug it: When your app cannot connect to the database, check the actual service name first:
kubectl get svc -n dream-team | grep post
# dt-postgresql ClusterIP 10.96.45.12 <none> 5432/TCPImage Tag Gotcha#
Bitnami PostgreSQL does not publish a bare 17 tag. If you set image.tag: "17", the pull will fail:
# WRONG - this tag does not exist
image:
tag: "17"
# CORRECT - omit the tag entirely, let the chart use its default
# (or use the full tag like "17.2.0-debian-12-r5")initdb.scripts Run Once#
The initdb.scripts block only executes on the first boot of the PostgreSQL container. A semaphore file inside the data volume prevents re-execution. If you need to change init scripts, you must delete the PVC and let the StatefulSet recreate it:
kubectl delete pvc data-dt-postgresql-0 -n dream-team
kubectl delete pod dt-postgresql-0 -n dream-team
# Pod will be recreated by StatefulSet, PVC will be reprovisioned, init scripts will runMattermost: Two Naming Surprises#
The Mattermost Team Edition Helm chart has its own naming quirks.
Service name ignores the release name. Regardless of what you name your release, the service is always mattermost-team-edition:
helm upgrade --install my-mm mattermost/mattermost-team-edition ...
kubectl get svc -n dream-team
# mattermost-team-edition ClusterIP 10.96.88.3 <none> 8065/TCP
# NOT "my-mm-mattermost-team-edition"Connection string format matters. The externalConnectionString value should NOT include the postgres:// prefix because the chart adds it:
# WRONG - double prefix results in "postgres://postgres://..."
externalConnectionString: "postgres://mmuser:password@dt-postgresql:5432/mattermost?sslmode=disable"
# CORRECT - just the credentials and host
externalConnectionString: "mmuser:password@dt-postgresql:5432/mattermost?sslmode=disable"CRD Ordering: Install Order Matters#
If you install a chart that creates ServiceMonitor resources before the Prometheus Operator CRDs exist, Helm will fail. The fix is to install CRDs first, or disable ServiceMonitor creation:
# Option 1: Install CRDs first
helm upgrade --install prometheus-crds prometheus-community/prometheus-operator-crds
# Option 2: Disable ServiceMonitor in the chart
helm upgrade --install dt-postgresql bitnami/postgresql \
--set metrics.serviceMonitor.enabled=falseLabel Selector Immutability#
Once a Deployment or StatefulSet is created, Kubernetes does not allow you to change its spec.selector.matchLabels. If a chart update changes label selectors, you will see:
Error: UPGRADE FAILED: cannot patch "my-app" with kind Deployment:
Deployment.apps "my-app" is invalid: spec.selector: Invalid value: ... field is immutableThe only fix is to delete and recreate the resource:
kubectl delete deployment my-app -n dream-team
helm upgrade --install my-app ./my-chartSafe Helm Patterns#
helm upgrade --install is idempotent. Use it in Makefile targets without worrying about “already exists” errors:
.PHONY: db
db:
helm upgrade --install dt-postgresql bitnami/postgresql \
--namespace dream-team --create-namespace \
-f values/postgresql.yaml --wait --timeout 120s
Quick Debugging Checklist#
- Service not found? Run
kubectl get svc -n <namespace>to see actual names. - Pod not starting? Check
kubectl describe pod <name>for image pull errors (bad tags). - Init scripts did not run? Delete the PVC to force re-initialization.
- Connection refused? Verify the connection string format – some charts add protocol prefixes automatically.
- Upgrade failed on selectors? Delete the resource and re-run the install.