What's Actually Happening
Helm chart installation fails during deployment. Chart does not install successfully to Kubernetes cluster.
The Error You'll See
```bash $ helm install my-release mychart/
Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest ```
Template error:
Error: INSTALLATION FAILED: template: mychart/templates/deployment.yaml: error converting YAML to JSONDependency error:
Error: INSTALLATION FAILED: found in Chart.yaml, but missing in charts/ directory: subchartResource conflict:
Error: INSTALLATION FAILED: rendered manifests contain a resource that already existsWhy This Happens
- 1.Invalid YAML syntax - Template generates invalid YAML
- 2.Missing dependencies - Chart dependencies not downloaded
- 3.Invalid values - Wrong or missing required values
- 4.Resource conflicts - Resources already exist in cluster
- 5.RBAC issues - Insufficient permissions
- 6.CRD not installed - Custom Resource Definition missing
Step 1: Debug Chart Templates
```bash # Dry run installation: helm install my-release mychart/ --dry-run --debug
# Render templates without installing: helm template my-release mychart/
# Render to file: helm template my-release mychart/ > rendered.yaml
# Validate rendered YAML: kubectl apply --dry-run=client -f rendered.yaml
# Check specific template: helm template my-release mychart/ -x templates/deployment.yaml
# Show computed values: helm install my-release mychart/ --dry-run --debug 2>&1 | grep -A100 "USER-SUPPLIED VALUES" ```
Step 2: Check Chart Dependencies
```bash # Check Chart.yaml dependencies: cat mychart/Chart.yaml
# Look for: # dependencies: # - name: subchart # version: 1.x.x # repository: https://charts.example.com
# Download dependencies: helm dependency update mychart/
# Or: helm dependency build mychart/
# List dependencies: helm dependency list mychart/
# Check charts directory: ls mychart/charts/
# If subcharts missing: helm repo add myrepo https://charts.example.com helm dependency update mychart/
# For local dependencies: # Place in charts/ directory: cp -r ../subchart mychart/charts/ ```
Step 3: Validate Values
```bash # Check default values: cat mychart/values.yaml
# Override values: helm install my-release mychart/ -f custom-values.yaml
# Set specific values: helm install my-release mychart/ --set image.tag=v1.0.0
# Set multiple values: helm install my-release mychart/ \ --set image.tag=v1.0.0 \ --set service.type=LoadBalancer \ --set replicaCount=3
# Check required values in templates: grep -r "required" mychart/templates/
# If required value missing: # Error: required value not provided: .Values.image.repository
# Provide required value: helm install my-release mychart/ --set image.repository=myimage ```
Step 4: Fix Template Syntax
```yaml # Common template errors:
# 1. Missing quote around value: # BAD: image: {{ .Values.image.repository }}:{{ .Values.image.tag }}
# GOOD: image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
# 2. Wrong indentation: # BAD (must align with key): spec: containers: - name: myapp image: myimage # Wrong indent
# GOOD: spec: containers: - name: myapp image: myimage
# 3. Invalid condition: # BAD: {{ if .Values.enabled }} # If .Values.enabled is undefined, error
# GOOD: {{ if .Values.enabled | default false }}
# 4. Missing . in values reference: # BAD: {{ .Values.imageTag }} # Wrong
# GOOD: {{ .Values.image.tag }}
# Validate template: helm lint mychart/
# With values: helm lint mychart/ -f custom-values.yaml ```
Step 5: Check Resource Conflicts
```bash # Check if resources exist: kubectl get all -n namespace
# Check specific resource: kubectl get deployment my-release-mychart -n namespace
# If resource exists from different release: # Option 1: Use different release name: helm install my-release-2 mychart/
# Option 2: Delete existing resource: kubectl delete deployment my-release-mychart
# Option 3: Force replace (dangerous): helm install my-release mychart/ --force
# Check for existing Helm releases: helm list -A
# Uninstall previous release: helm uninstall my-release -n namespace
# Check for orphaned resources: kubectl get all -A -l app.kubernetes.io/managed-by=Helm ```
Step 6: Check RBAC Permissions
```bash # Check user permissions: kubectl auth can-i create deployments kubectl auth can-i create secrets kubectl auth can-i create configmaps
# Check in namespace: kubectl auth can-i create deployments -n mynamespace
# Check for specific resource: kubectl auth can-i create customresourcedefinitions
# If permission denied: # Create Role/RoleBinding or ClusterRole/ClusterRoleBinding
# Example Role: apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: helm-deployer namespace: mynamespace rules: - apiGroups: [""] resources: ["*"] verbs: ["*"] - apiGroups: ["apps"] resources: ["*"] verbs: ["*"]
# Bind to user: kubectl create rolebinding helm-deployer \ --role=helm-deployer \ --user=your-user \ -n mynamespace ```
Step 7: Handle CRD Issues
```bash # Check if CRD exists: kubectl get crd
# Install CRD manually: kubectl apply -f https://raw.githubusercontent.com/.../crd.yaml
# Or use crd-install hook in chart: # In template: {{- if .Values.installCRD }} apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: name: myresource.example.com annotations: "helm.sh/hook": crd-install spec: ... {{- end }}
# Install with CRD: helm install my-release mychart/ --set installCRD=true
# Check CRD installation: kubectl get crd myresource.example.com
# CRD must exist before resources using it ```
Step 8: Check Namespace Issues
```bash # Install to specific namespace: helm install my-release mychart/ -n mynamespace
# Create namespace if not exists: helm install my-release mychart/ -n mynamespace --create-namespace
# Check namespace exists: kubectl get namespace mynamespace
# Check resources in namespace: helm list -n mynamespace
# Check namespace labels (for network policies): kubectl get namespace mynamespace --show-labels
# If namespace has restrictions: kubectl get networkpolicy -n mynamespace kubectl get limitrange -n mynamespace kubectl get resourcequota -n mynamespace ```
Step 9: Check Helm Version Compatibility
```bash # Check Helm version: helm version
# Check chart apiVersion in Chart.yaml: # apiVersion: v2 # Helm 3 # apiVersion: v1 # Helm 2
# Helm 3 features: # - apiVersion: v2 # - Helm test framework # - Library charts
# If using Helm 2 chart with Helm 3: # Convert Chart.yaml: # Add apiVersion: v2 # Remove requirements.yaml (use dependencies in Chart.yaml)
# Check Kubernetes version compatibility: # In Chart.yaml: # kubeVersion: ">= 1.20.0"
# Check cluster version: kubectl version
# Skip kubeVersion check: helm install my-release mychart/ --disable-openapi-validation ```
Step 10: Helm Chart Verification Script
```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-helm-chart.sh #!/bin/bash
CHART=$1 NAMESPACE=${2:-"default"}
echo "=== Helm Version ===" helm version
echo "" echo "=== Chart.yaml ===" cat $CHART/Chart.yaml
echo "" echo "=== Chart Dependencies ===" helm dependency list $CHART 2>/dev/null || echo "No dependencies"
echo "" echo "=== Values.yaml ===" cat $CHART/values.yaml | head -50
echo "" echo "=== Helm Lint ===" helm lint $CHART/
echo "" echo "=== Template Render ===" helm template test-release $CHART/ 2>&1 | head -100
echo "" echo "=== Dry Run ===" helm install test-release $CHART/ --dry-run -n $NAMESPACE 2>&1 | tail -50
echo "" echo "=== RBAC Check ===" kubectl auth can-i create deployments -n $NAMESPACE kubectl auth can-i create secrets -n $NAMESPACE kubectl auth can-i create configmaps -n $NAMESPACE
echo "" echo "=== Existing Releases ===" helm list -n $NAMESPACE
echo "" echo "=== Recommendations ===" echo "1. Fix any lint errors" echo "2. Download missing dependencies: helm dependency update" echo "3. Provide required values: --set or -f values.yaml" echo "4. Check RBAC permissions" echo "5. Verify namespace exists" echo "6. Check for resource conflicts" EOF
chmod +x /usr/local/bin/check-helm-chart.sh
# Usage: /usr/local/bin/check-helm-chart.sh ./mychart default
# Quick test: alias helm-debug='helm install --dry-run --debug' ```
Helm Chart Checklist
| Check | Command | Expected |
|---|---|---|
| Chart syntax | helm lint | No errors |
| Dependencies | helm dependency list | All present |
| Template valid | helm template | Valid YAML |
| Values correct | helm template --debug | Expected values |
| RBAC | kubectl auth can-i | Allowed |
| No conflicts | helm list | Unique release |
Verify the Fix
```bash # After fixing chart installation
# 1. Install chart helm install my-release mychart/ -n namespace // Release installed
# 2. Check release status helm status my-release -n namespace // STATUS: deployed
# 3. Check resources kubectl get all -n namespace -l app.kubernetes.io/instance=my-release // Resources created
# 4. Check pods running kubectl get pods -n namespace -l app.kubernetes.io/instance=my-release // Pods Running
# 5. Test with helm test helm test my-release -n namespace // Tests pass
# 6. Check history helm history my-release -n namespace // Revision 1 deployed ```
Related Issues
- [Fix Kubernetes Deployment Not Working](/articles/fix-kubernetes-deployment-not-working)
- [Fix Kubernetes Service Not Found](/articles/fix-kubernetes-service-not-found)
- [Fix Kubernetes Ingress Not Routing Traffic](/articles/fix-kubernetes-ingress-not-routing-traffic)