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:

bash
Error: INSTALLATION FAILED: template: mychart/templates/deployment.yaml: error converting YAML to JSON

Dependency error:

bash
Error: INSTALLATION FAILED: found in Chart.yaml, but missing in charts/ directory: subchart

Resource conflict:

bash
Error: INSTALLATION FAILED: rendered manifests contain a resource that already exists

Why This Happens

  1. 1.Invalid YAML syntax - Template generates invalid YAML
  2. 2.Missing dependencies - Chart dependencies not downloaded
  3. 3.Invalid values - Wrong or missing required values
  4. 4.Resource conflicts - Resources already exist in cluster
  5. 5.RBAC issues - Insufficient permissions
  6. 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

CheckCommandExpected
Chart syntaxhelm lintNo errors
Dependencieshelm dependency listAll present
Template validhelm templateValid YAML
Values correcthelm template --debugExpected values
RBACkubectl auth can-iAllowed
No conflictshelm listUnique 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 ```

  • [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)