ingress-nginx-controller service is still not removed after uninstalling chart
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.
Introduction
When helm uninstall finishes but the ingress-nginx-controller Service still exists, the problem is usually not Helm itself. In most cases the Service was recreated outside the release, is stuck behind a finalizer, or is waiting on cloud load balancer cleanup that has not completed yet.
What Helm Actually Deletes
Helm removes the resources that belong to the release manifest it has recorded. If the Service was changed after install, recreated manually, or created by another controller, Helm may no longer be the owner that can clean it up.
Start by confirming whether the release is actually gone.
If the release no longer exists, inspect the Service directly.
Look for these details:
- '
metadata.ownerReferences' - '
metadata.finalizers' - '
metadata.labels' - '
metadata.annotations'
If there is no owner reference back to the Helm-managed workload, the object may have drifted away from the original release.
LoadBalancer Cleanup Is a Common Reason
The most common leftover object is a Service of type LoadBalancer. Deleting that Service asks the cloud controller to tear down the external load balancer, public IP, forwarding rules, and similar infrastructure. Until that cleanup is done, Kubernetes may keep a finalizer on the Service.
You can see this with:
If the output shows a finalizer and the object has a deletionTimestamp, deletion has started but has not completed. That usually means one of these conditions applies:
- the cloud controller manager is not running
- cloud credentials are broken
- the load balancer resource was modified manually in the cloud console
- the cluster has already lost the controller that knows how to finish cleanup
In that state Helm is done, but Kubernetes is still waiting for infrastructure cleanup.
Verify Whether the Service Was Recreated
Sometimes the chart was uninstalled correctly and then another process recreated the Service. This happens with GitOps systems, leftover manifests, or another Helm release using the same name.
Check for matching resources and automation:
If you see labels from Argo CD, Flux, or another release, the object is being managed elsewhere. In that case deleting it manually will only make it come back.
Safe Removal Workflow
A practical cleanup flow looks like this:
If the Service still exists and is not already terminating, try a normal delete:
If it is stuck because a finalizer can no longer complete, remove the finalizer only after you confirm the external load balancer is already gone or you are willing to clean cloud resources manually.
Use that last step carefully. It tells Kubernetes to forget the remaining controller cleanup work.
Check for Namespace and Hook Leftovers
Helm uninstalling a release does not delete the namespace unless you delete it yourself. Hook-created jobs, admission webhooks, or custom configuration created outside the main manifest can also remain.
These commands help with a broader audit:
That gives you a quick view of whether the leftover Service is part of a wider uninstall problem.
Common Pitfalls
- Assuming
helm uninstalldeletes anything with a similar name, even if another tool recreated it. - Forgetting that
LoadBalancerServices often depend on cloud-side cleanup before deletion completes. - Removing finalizers before checking whether cloud resources still exist.
- Looking only at Helm output instead of inspecting the live Service object.
- Ignoring GitOps or admission controllers that may recreate the Service after deletion.
Summary
- Helm removes release-owned resources, not arbitrary objects with matching names.
- A leftover
ingress-nginx-controllerService is often stuck on cloud load balancer cleanup. - Inspect
ownerReferences, labels, annotations, and finalizers before forcing deletion. - If another controller recreated the Service, fix that source first.
- Remove finalizers only when you understand the external cleanup consequences.
Related reading
- Ingress and Ingress controller how to use them with NodePort Services?
- ingress can not get the default http backend
- Ingress configuration for k8s in different namespaces
- Ingress controller - proxy pass based on user agent
- Ingress controller to route TCP traffic
- Ingress controller vs api gateway
- Ingress is not working for application gateway ingress controller AGIC add-on of AKS
- “init terminating in do_boot” Windows 8.1 Rabbit MQ fails to start

System Design Fundamentals
Build a strong foundation in designing scalable, reliable distributed systems.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
System Design practice on Codemia
Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.