ingress-nginx Is Retired and a New CVE Just Landed: The 24-Hour Mitigation Runbook and What to Run Instead
ingress-nginx reached end of maintenance in 2026, so any CVE filed after that date - including CVE-2026-116472 - will never get an official upstream patch. Here is the four-step containment runbook you can apply in 24 hours, a fair comparison of the maintained ingress controllers and Gateway API implementations that should replace it, and a hostname-by-hostname migration plan with rollback.
No patch is coming for CVE-2026-116472, so stop waiting for one. The Kubernetes project ended ingress-nginx maintenance in March 2026, and the official advisory for this CVE says it plainly: "Kubernetes will not be issuing a fix for this CVE" (Kubernetes advisory, issue #143852). You can contain it today with one ConfigMap change, then you need to plan your exit.
The good news is that this specific CVE is rated low. The bad news is that it will not be the last one, and every future ingress-nginx CVE will get the same answer.
No upstream fix exists or will exist. CVE-2026-116472 was published on November 5, 2026 with a CVSS 3.1 score of 2.7 (Low), and every ingress-nginx version is listed as affected (CVE.org record). The Kubernetes Security Response Committee still publishes the advisory, but no patched release or image will follow.
The fastest mitigation is one ConfigMap key. Set annotations-risk-level: Medium in the controller ConfigMap, or reject the mirror-target annotation with an admission policy. Both are the official workarounds.
Who can create an Ingress is your real privilege boundary. CVE-2026-116472 and three of the five IngressNightmare CVEs required only Ingress write access. CVE-2025-1974 needed no credentials at all, just network access to the admission webhook.
Treat any fork as a short bridge. SUSE already ships a fix in its Rancher Prime fork, and Microsoft patches the AKS add-on through November 2026. Use vendor-backed forks to buy weeks while you migrate.
Replace it with a maintained Gateway API implementation. Envoy Gateway, Istio, Cilium, Traefik, NGINX Gateway Fabric, Kong, or your cloud's controller all pass Gateway API conformance today. InGate, the planned successor, was retired before it matured.
Qovery customers did not run this by hand. We migrated the clusters we manage from ingress-nginx to Envoy Gateway as a platform rollout, in customers' own AWS, GCP, Azure, Scaleway, or existing Kubernetes clusters.
What does "ingress-nginx maintenance ended" actually mean for a CVE like CVE-2026-116472?
It means the CVE gets an advisory and never gets a fix. The Kubernetes Security Response Committee still assigns and publishes CVEs for ingress-nginx, but there is no release pipeline left to ship a patched version, so your only paths are mitigation, a vendor fork, or replacement.
The retirement was announced on November 11, 2025: "Best-effort maintenance will continue until March 2026. Afterward, there will be no further releases, no bugfixes, and no updates to resolve any security vulnerabilities that may be discovered" (Kubernetes blog). The last controller release, v1.15.1, shipped on March 19, 2026, and the GitHub repository is now archived (ingress-nginx releases).
In practice, retirement means:
No new release tags and no new controller images.
No backports to older minors.
Advisories without fixes. The SRC still files CVEs, as it did for CVE-2026-116472, but the remediation section points you to "your vendor".
Existing deployments keep running. Helm charts and images stay available, which is exactly why so many clusters still run it.
What CVE-2026-116472 actually is
I checked the record on CVE.org, NVD, and the GitHub Advisory Database before writing this. It is real, and it is a low-severity self-DoS:
Mechanism: due to a missing check, the mirror-target annotation can target an unauthenticated configuration API inside the controller. Corrupting it drops all traffic through that ingress-nginx instance until a config change or restart.
Who can trigger it: a user with permission to create an Ingress. That is why the CVSS vector says PR:H and the score is 2.7 (Kubernetes advisory).
Affected versions: all of them. SUSE fixed it in 1.15.2-prime1 of its RKE2 fork.
Low severity is not a reason to relax. The triage rule for any ingress-nginx CVE published after March 2026 is the same regardless of score: mitigate now, decide fork versus replace this week, finish the migration this quarter.
How big is the blast radius?
Big. Wiz found that over 41% of internet-facing clusters ran ingress-nginx, and that about 43% of cloud environments were vulnerable to the IngressNightmare chain in March 2025, with over 6,500 clusters exposing the admission controller to the internet (Wiz Research).
Check managed add-ons too, because in many clusters nobody on the current team installed it. The AKS application routing add-on is built on ingress-nginx, and Microsoft supports critical patches for it only through November 2026 (Microsoft Learn). RKE2 shipped ingress-nginx as its default until v1.36 switched new clusters to Traefik (RKE2 docs).
An unpatchable component in your request path is also an audit finding. Your scanner will flag it forever, and your SOC 2 or PCI DSS auditor will ask for either a remediation date or a signed risk acceptance. CISA's BOD 26-04 lists decommissioning as a valid remediation, and for a retired project that is the only permanent one.
How do we mitigate ingress-nginx right now, in the next 24 hours?
Shrink what an Ingress author and a network attacker can do to the controller in four moves: block high-risk annotations, block mirror-target at admission, tighten RBAC, and isolate the controller with NetworkPolicy. One engineer can apply all of it in about 4 to 6 hours, and the first two moves fully cover CVE-2026-116472.
Step 1: Inventory (15 minutes)
Find every controller, its exact image, and who owns it:
BASH
kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx \
-o jsonpath='{range .items[*]}{.metadata.namespace}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
helm list -A | grep -i nginx
kubectl get ingressclass
aws eks list-addons --cluster-name <cluster-name>
az aks show -g <resource-group> -n <cluster-name> --query ingressProfile
Then find Ingresses that already use mirror-target. The advisory says localhost addresses in that annotation may indicate an exploit attempt:
BASH
kubectl get ingress -A -o json | jq -r '.items[]
| select(.metadata.annotations["nginx.ingress.kubernetes.io/mirror-target"] != null)
| "\(.metadata.namespace)/\(.metadata.name)\t\(.metadata.annotations["nginx.ingress.kubernetes.io/mirror-target"])"'
Step 2: Lower the annotation risk level (30 minutes)
annotations-risk-level defaults to High, and mirror-target is rated High (annotation risk table). Setting it to Medium rejects every High and Critical annotation, which is the official workaround for this CVE. allow-snippet-annotations already defaults to false on recent versions (ConfigMap docs), so confirm nobody turned it back on.
This breaks things. List what will stop applying first:
BASH
kubectl get ingress -A -o json | jq -r '.items[] | .metadata as $m
| ($m.annotations // {}) | keys[]
| select(test("nginx.ingress.kubernetes.io/(auth-url|auth-signin|auth-tls-error-page|auth-tls-match-cn|mirror-host|mirror-target|modsecurity-transaction-id|proxy-ssl-name|server-alias|upstream-hash-by|.*-snippet)$"))
| "\($m.namespace)/\($m.name)\t\(.)"'
If that list includes auth-url for external auth, skip to the admission policy in Step 3 instead. Otherwise, apply through Helm so the next upgrade does not revert it:
Then audit who can write Ingress objects. The ingress-nginx README says the project "assumes that users that can create Ingress objects are administrators of the cluster" (README). Treat that list of identities exactly that way:
The default chart ClusterRole lets the controller list and watch Secrets in every namespace. If one controller serves one namespace, set controller.scope.enabled=true, controller.scope.namespace=<ns>, and rbac.scope=true to swap it for a namespaced Role. If it serves the whole cluster, you cannot scope it without splitting controllers, so accept that and move faster on the migration.
Step 4: Isolate the controller with NetworkPolicy (1 to 2 hours)
Do not block the controller's egress to the API server. It watches Ingresses, Services, and Secrets through that connection and stops working without it. Lock down inbound access to the admission webhook instead, which is the path CVE-2025-1974 used, and block the cloud metadata endpoint:
Add a rule for port 10254 if Prometheus scrapes the controller. Kubelet probes keep working because traffic from the pod's own node is always allowed (NetworkPolicy docs). Test the control plane CIDR in staging first: a wrong value makes every Ingress create fail.
Edge filtering and detection
A WAF rule will not help with CVE-2026-116472, because the attack arrives as an Ingress object through the Kubernetes API, not as an HTTP request. Keep AWS WAF, Google Cloud Armor, Azure WAF, or Cloudflare rules for future request-path CVEs that have a stable signature.
For detection, search Kubernetes audit logs for Ingress create and update events from unusual service accounts, check controller logs for unexpected reloads, and alert on any mirror-target value pointing at 127.0.0.1 or localhost.
Action
Exact key or command
Attack class it blocks
Time
Breaking-change risk
Keep after migration?
Inventory controllers and add-ons
kubectl get pods -A -l app.kubernetes.io/name=ingress-nginx
Qovery gives your team self-service deployments and managed cluster upgrades on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.
Should we run a community fork of ingress-nginx instead of migrating?
Run a vendor-backed fork only as a time-boxed bridge, for 4 to 8 weeks, while the migration runs in parallel. A fork without a named vendor, a security contact, and signed images is a dependency on a stranger in your request path, which is worse than the retired original.
The credible forks today come from vendors you may already pay. SUSE fixed CVE-2026-116472 in its Rancher Prime fork (Kubernetes advisory), and Microsoft patches the AKS add-on through November 2026. Both vendors also tell you to leave: RKE2 removes ingress-nginx for new clusters in v1.37, and AKS points to Gateway API.
Before adopting any fork, get answers to five questions:
Who funds it, and what happens when that funding stops?
Does it track upstream nginx security releases, not just the controller Go code?
Where is the image hosted, who can push to it, and is it signed with provenance and an SBOM?
Is there a published security contact and response SLA?
What is its own end-of-life date?
"We'll just build our own image from the last commit" is a permanent commitment. You now own nginx CVE tracking, Go dependency CVEs, base image rebuilds, and CI, forever. I've seen teams pick that path to avoid a two-week migration and still be carrying it a year later.
Option
Cost (my estimate)
How long it buys you
Who it fits
Failure mode
Mitigate in place
1 to 2 engineer-days
Until the next CVE that config cannot block
Everyone, as step one
A request-path RCE with no config workaround
Vendor fork (SUSE, AKS add-on)
1 to 3 days to switch, plus a contract
Until the vendor's own end date
Teams already on RKE2 or AKS
Vendor date arrives before your migration does
Self-built fork
3 to 5 engineer-days per quarter, forever
As long as you keep paying
Almost nobody
Silent drift from upstream nginx security fixes
Migrate now
Days to weeks, scoped by annotation usage
Years, on a maintained project
Everyone, eventually
Underestimating annotation translation
InGate is not an option. The Kubernetes project states that "InGate development never progressed far enough to create a mature replacement; it will also be retired" (Kubernetes blog).
What should replace ingress-nginx long term, and how do the options compare?
Replace ingress-nginx with a maintained controller that passes Gateway API conformance and has a real security response process. SIG Network and the SRC "recommend that all Ingress NGINX users begin migration to Gateway API or another Ingress controller immediately" (Kubernetes blog), and choosing another Ingress-only controller just schedules the next migration.
Pick by context:
Single cloud, plain L7 routing and TLS: your cloud's controller (AWS Load Balancer Controller, GKE Gateway, Azure Application Gateway for Containers) has the lowest ops burden.
Portability across clouds: Envoy Gateway or Traefik.
Already running a service mesh: use Istio's gateway.
Already running Cilium as CNI: Cilium Gateway.
Want to keep an nginx data plane: NGINX Gateway Fabric, with the understanding that annotations do not carry over.
Not listed; N42 Gateway is the listed HAProxy implementation
None native
Medium
HAProxy shops
AWS Load Balancer Controller
AWS
AWS ALB and NLB
Partially conformant
None
Low
EKS only
GKE Gateway
Google
Google Cloud load balancers
Conformant
None
Low
GKE only
Azure Application Gateway for Containers
Microsoft
Azure managed
Not listed; supports Ingress and Gateway API per Microsoft
None
Low
AKS only
InGate
Kubernetes SIG Network
n/a
Retired before maturity
n/a
n/a
Nobody
Annotations are the real migration cost. Rewrite rules with capture groups, snippets, auth-url and auth-signin external auth, cookie-based canaries, session affinity, proxy-body-size, and timeouts all need translation. ingress2gateway (v1.2.0, July 2026) converts common ingress-nginx annotations, but its README says it "is not intended to copy annotations", and it flags capture-group rewrites and cookie canaries as unsupported.
Gateway API also fixes the root problem. GatewayClass and Gateway belong to the platform team, HTTPRoute belongs to app teams, so you stop hand-reviewing every Ingress for dangerous annotations.
What does a safe migration off ingress-nginx look like, step by step?
Install the new controller beside the old one and move traffic one hostname at a time. A parallel install with its own GatewayClass and load balancer turns rollback into a DNS change measured in minutes.
Install side by side. Give the new controller its own GatewayClass and load balancer. Lower DNS TTLs to 60 seconds a day before cutover.
Translate, then read the diff. Run ingress2gateway print --providers=ingress-nginx and list every annotation it could not convert. Size the project from that list.
Validate on real hostnames. Read five ingress-nginx behaviors that Gateway API does not copy, such as case-insensitive prefix regex and automatic trailing-slash redirects. A preview environment per pull request catches these with real certificates before production does.
Shift one hostname at a time. Start with the lowest-traffic host and keep the hardened ingress-nginx live until the last one moves.
Test what always breaks. cert-manager HTTP-01 challenges, external-dns record ownership, WebSockets, gRPC, large request bodies, client IP preservation through proxy protocol and X-Forwarded-For, and sticky sessions.
Decommission completely. Delete the Deployment, RBAC, the ValidatingWebhookConfiguration, and the cloud load balancer. Confirm nothing still uses the old class with kubectl get ingress -A -o wide. An idle AWS ALB or NLB still bills $0.0225 per hour, about $16 a month before capacity units (AWS pricing), and it stays an exposed endpoint.
A handful of simple hostnames takes days. Heavy snippet, external auth, and canary usage takes weeks. Our own move across the clusters Qovery manages held to the architecture we planned, but the calendar slipped by seven months, mostly because we would not force production clusters onto a stack their owners had not validated (Qovery engineering).
How do we stop the next retired-component fire before it starts?
Treat ingress, CNI, and cluster add-ons as versioned platform surface with a named owner, a tested upgrade path, and an exit plan. The real failure behind this CVE is a load-bearing component in the request path that nobody owned.
Keep an add-on inventory with maintainer health, CVE history, CNCF maturity, and end-of-life dates. Review it quarterly.
Require CNCF graduation or a vendor support contract for anything in the request path. Incubating projects need a named internal owner.
Standardize on Gateway API so the next swap is a GatewayClass change, not a manifest rewrite in every team's repo.
Measure time-to-upgrade as a platform SLO. If upgrading your ingress controller is scary, the CVE is not your problem - your upgrade path is.
This is the work Qovery takes off your plate. Qovery is an internal developer platform that deploys and operates your apps inside your own AWS, GCP, Azure, Scaleway, or existing Kubernetes cluster, so your cloud bill, discounts, and data stay in your account. Qovery is not an ingress controller. It manages the ingress layer and cluster upgrades for you, which is how we moved our customers from ingress-nginx to Envoy Gateway as a phased rollout with a rollback at every step (the plan).
Teams get git-push deployments, preview environments per pull request to validate routing changes, per-environment RBAC, and environment auto-stop, without a dedicated DevOps engineer babysitting add-on versions.
How do I run this migration from Claude Code or Cursor with Qovery?
Install the Qovery Agent Skills once and your coding agent can spin up a preview environment in your own cloud account, deploy the new routing path, and validate it before you touch production DNS. The skills handle deployment, and the MCP Server operates what already exists, read-only by default.
Install for every compatible agent (Claude Code, Cursor, Codex, OpenCode, Gemini CLI), globally:
Add the MCP Server to Claude Code (OAuth, read-only by default) so the agent can inspect environments without changing them:
BASH
claude mcp add --transport http qovery https://mcp.qovery.com/mcp --callback-port 4242
Enable write access only when you explicitly want the agent to act. It also requires turning on write access in the Qovery Console:
BASH
claude mcp add --transport http qovery "https://mcp.qovery.com/mcp?read_write=true" --callback-port 4242
Then ask in plain language: "spin up a preview environment on my AWS account and validate the new ingress routing before I cut DNS over". The relevant skills are qovery-onboard, qovery-deploy, qovery-preview, and qovery-troubleshoot. Setup details are in the AI agent quickstart and the Claude Code integration page.
Frequently asked questions
Is there an official patch for CVE-2026-116472 in ingress-nginx?
No. The Kubernetes advisory for CVE-2026-116472 states that Kubernetes will not issue a fix because ingress-nginx maintenance ended in March 2026. The official mitigations are setting annotations-risk-level to Medium or Low, or rejecting the mirror-target annotation with an admission controller. SUSE ships a fix in version 1.15.2-prime1 of its Rancher Prime fork.
What is the fastest mitigation if I cannot migrate off ingress-nginx this week?
The fastest ingress-nginx mitigation is setting annotations-risk-level: Medium in the controller ConfigMap, which blocks every High and Critical annotation, including mirror-target. Check first whether you rely on auth-url, mirror, or server-alias annotations, because they stop applying. If you do, use a ValidatingAdmissionPolicy that rejects only mirror-target, then restrict who can create Ingress objects.
Which ingress controller should replace ingress-nginx in 2026?
The best ingress-nginx replacement in 2026 depends on context. Use your cloud's controller for single-cloud L7 routing, Envoy Gateway or Traefik for multi-cloud portability, Istio's gateway if you already run a mesh, and Cilium Gateway if Cilium is your CNI. Prefer a Gateway API conformant implementation from the official implementations page over another Ingress-only controller.
Is a community fork of ingress-nginx safe to run in production?
A community fork of ingress-nginx is safe only as a short bridge, and only if a named vendor backs it with signed images, a security contact, and a published end date. SUSE's Rancher Prime fork and Microsoft's AKS add-on meet that bar for now. An anonymous fork, or one you build yourself from the last commit, moves the maintenance burden onto your team permanently.
Do I have to move to Gateway API, or can I stay on the Ingress API?
You can stay on the Ingress API, because Ingress is not removed from Kubernetes, and the Kubernetes project lists maintained Ingress controllers as an acceptable path. Gateway API is the recommended direction, though, and it replaces annotation sprawl with typed routes and a clean split between platform and app team ownership. Moving to a controller that supports both, such as Traefik or Envoy Gateway, keeps both options open.
How long does migrating from ingress-nginx to a Gateway API controller usually take?
Migrating from ingress-nginx to a Gateway API controller takes days for a few simple hostnames and weeks for clusters with heavy snippet, external auth, and canary usage. The number of annotations that ingress2gateway cannot convert drives the timeline more than the number of hostnames. Plan for slippage when production owners must validate each cutover.
Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.
Next step
Ship faster on infrastructure you control.
Qovery gives your team self-service deployments and managed cluster upgrades on your own AWS, GCP, Azure, or Scaleway account - or your existing Kubernetes cluster. Start deploying in under 10 minutes.