What's Actually Happening

Helm packages Kubernetes resources into charts. When you install or upgrade a chart, Helm renders templates into Kubernetes manifests and applies them. Failures occur when templates error, values are wrong, or Kubernetes rejects the manifests.

The Error You'll See

```bash $ helm install my-release my-chart/ Error: INSTALLATION FAILED: unable to build kubernetes objects from release manifest: error validating "": error validating data: ValidationError(Deployment.spec.template.spec.containers[0].resources.requests): unknown field "cpu" in io.k8s.api.core.v1.ResourceRequirements

# Or during upgrade: $ helm upgrade my-release my-chart/ Error: UPGRADE FAILED: another operation (install/upgrade/rollback) is already in progress ```

Why This Happens

  1. 1.Template syntax error - Invalid Go template syntax
  2. 2.Invalid values - Wrong values.yaml configuration
  3. 3.Kubernetes validation error - Manifest doesn't match API schema
  4. 4.Release lock - Previous operation incomplete
  5. 5.Missing dependencies - Chart subcharts not updated
  6. 6.CRD not installed - Custom Resource Definition missing
  7. 7.Namespace doesn't exist - Target namespace missing

Step 1: Dry Run to See Rendered Manifest

bash
helm install my-release my-chart/ --dry-run --debug

Shows rendered templates without applying:

bash
NAME: my-release
NAMESPACE: default
STATUS: pending-install
MANIFEST:
---
# Source: my-chart/templates/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-release-my-chart
...

Look for errors in the output.

Step 2: Template Debug Mode

bash
helm template my-release my-chart/ --debug

Shows all rendered templates. Check for: - Empty values - Missing required fields - Incorrect API versions

Step 3: Validate Values Configuration

bash
helm install my-release my-chart/ -f values.yaml --dry-run

Check values.yaml:

```yaml # Common mistakes replicas: "3" # Wrong: should be integer replicas: 3 # Correct

resources: requests: cpu: "500m" # Correct format memory: 512Mi # Correct

# Missing required values image: repository: nginx # Required # tag: latest # Missing if required ```

Step 4: Fix Template Syntax Errors

Template errors show in output:

bash
Error: INSTALLATION FAILED: parse error in "deployment.yaml": template: my-chart/templates/deployment.yaml:10: unexpected "=" in operand

Fix template:

```yaml # Wrong template syntax {{ .Values.replicas = 3 }} # Invalid

# Correct replicas: {{ .Values.replicas }} ```

Step 5: Handle Release Lock Error

If Helm shows "operation already in progress":

```bash # Check release history helm history my-release

# If stuck, delete the lock secret kubectl delete secret sh.helm.release.v1.my-release.v1

# Or use --force to override lock helm upgrade my-release my-chart/ --force ```

Step 6: Update Chart Dependencies

bash
helm dependency update my-chart/

If chart has subcharts:

bash
Saving 2 charts
Downloading postgresql from repo https://charts.bitnami.com/bitnami
Downloading redis from repo https://charts.bitnami.com/bitnami
Deleting outdated charts

Step 7: Check CRD Requirements

If chart needs CRDs:

```bash # Check if CRD exists kubectl get crd | grep my-crd

# Install CRD first kubectl apply -f crds/

# Or use helm crd hook helm install my-release my-chart/ ```

Step 8: Create Missing Namespace

bash
helm install my-release my-chart/ -n my-namespace
Error: namespace "my-namespace" not found

Create namespace:

```bash kubectl create namespace my-namespace

# Or use --create-namespace helm install my-release my-chart/ -n my-namespace --create-namespace ```

Step 9: Rollback Failed Release

If upgrade failed but release exists:

```bash # Check history helm history my-release

REVISION STATUS CHART DESCRIPTION 1 superseded my-chart-1.0 Install complete 2 failed my-chart-1.1 Upgrade failed

# Rollback to previous revision helm rollback my-release 1 ```

Step 10: Clean Up Failed Release

If release is stuck:

```bash # Uninstall failed release helm uninstall my-release

# Or keep history helm uninstall my-release --keep-history

# Clean up manually kubectl delete all -l app.kubernetes.io/instance=my-release kubectl delete secret -l owner=helm,name=my-release ```

Verify the Fix

After fixing issues:

```bash helm install my-release my-chart/ --dry-run # Verify renders correctly helm install my-release my-chart/ # Apply

# Check release status helm status my-release

# Check resources created kubectl get all -l app.kubernetes.io/instance=my-release ```

Prevention Tips

Best practices for Helm:

```bash # Always dry-run first helm install my-release my-chart/ --dry-run --debug

# Use specific values file helm install my-release my-chart/ -f custom-values.yaml

# Validate values schema if chart has one helm lint my-chart/

# Update dependencies before install helm dependency update my-chart/

# Test with helm test helm test my-release ```