Introduction
Helm post-delete hooks run after the main resources are deleted during helm uninstall. These hooks typically perform cleanup tasks like removing external resources, sending notifications, or archiving data. When a post-delete hook resource gets stuck -- such as a Job that cannot complete or a Pod stuck in Terminating -- the uninstall process hangs, leaving orphaned resources in the namespace.
Symptoms
helm uninstallhangs indefinitely waiting for the post-delete hook to complete- Namespace cannot be deleted because hook resources are still present
kubectl get allshows hook jobs or pods stuck after uninstall- Hook Job has
Activestatus but no pods are running - Error message:
timed out waiting for the conditionduring uninstall
Common Causes
- Post-delete hook Job's container image not available, causing image pull errors
- Hook depends on a resource that was already deleted (e.g., ConfigMap or Secret)
- Hook Job has no
activeDeadlineSecondsand runs indefinitely - Namespace deletion triggered while hook is still running
- Hook pod stuck in
Terminatingdue to finalizer on a custom resource
Step-by-Step Fix
- 1.Identify the stuck hook resource: Check what is blocking the uninstall.
- 2.```bash
- 3.kubectl get jobs -n my-namespace
- 4.kubectl get pods -n my-namespace | grep hook
- 5.
` - 6.Delete the stuck hook resource manually: Force cleanup of the hook.
- 7.```bash
- 8.# Delete the stuck job
- 9.kubectl delete job my-release-cleanup-hook -n my-namespace --force --grace-period=0
- 10.# Remove any stuck pods
- 11.kubectl delete pod my-release-cleanup-hook-xxxxx -n my-namespace --force --grace-period=0
- 12.
` - 13.Remove finalizers if the resource is stuck in Terminating: Force deletion.
- 14.```bash
- 15.kubectl patch pod my-release-hook-xxxxx -n my-namespace \
- 16.-p '{"metadata":{"finalizers":[]}}' --type=merge
- 17.
` - 18.Clean up remaining Helm release data: Remove the release secret.
- 19.```bash
- 20.kubectl get secrets -n my-namespace -l owner=helm,name=my-release
- 21.kubectl delete secret sh.helm.release.v1.my-release.v1 -n my-namespace
- 22.
` - 23.Fix the hook for future uninstalls: Add timeout and error handling.
- 24.```yaml
- 25.apiVersion: batch/v1
- 26.kind: Job
- 27.metadata:
- 28.name: "{{ .Release.Name }}-cleanup"
- 29.annotations:
- 30."helm.sh/hook": post-delete
- 31."helm.sh/hook-delete-policy": before-hook-creation
- 32.spec:
- 33.activeDeadlineSeconds: 120
- 34.backoffLimit: 1
- 35.template:
- 36.spec:
- 37.containers:
- 38.- name: cleanup
- 39.image: busybox
- 40.command: ["sh", "-c", "echo cleanup && exit 0"]
- 41.restartPolicy: Never
- 42.
`
Prevention
- Set
activeDeadlineSecondson all hook jobs to prevent indefinite execution - Use
helm.sh/hook-delete-policy: before-hook-creationto clean up hook resources before running - Design post-delete hooks to be idempotent and tolerant of missing dependencies
- Test
helm uninstallin staging environments to identify hook issues before production - Monitor hook job completion in CI/CD pipelines after uninstall
- Keep post-delete hooks simple -- use them only for critical cleanup, not complex operations