The end of Ingress NGINX: how to plan a migration to Gateway API
The ingress-nginx repository has been archived since March 2026 and receives no security patches. How to take inventory, choose a replacement and move traffic without downtime.

Summary
The kubernetes/ingress-nginx repository has been archived and read-only since 24 March 2026: no more releases, no bug fixes, no security patches. Since then, a critical vulnerability has already been disclosed in NGINX itself, and the upstream project will not respond to it. There is no “just swap the image” replacement: migrating to Gateway API is a project, not an upgrade, and most of the work lies in annotations and undocumented behavior that applications have relied on for years. This article describes how to plan and execute it without downtime.
What exactly ended, and what did not
Kubernetes SIG Network and the Security Response Committee announced on 11 November 2025 that Ingress NGINX would be maintained on a “best effort” basis until March 2026. After that, according to the announcement, there would be no further releases, no bug fixes and no updates to address security vulnerabilities. Existing deployments keep working and the installation artifacts remain available.
Status as of October 2026: the GitHub repository was archived on 24 March 2026 and is read-only. The last line in the supported versions table is v1.15.1 with NGINX 1.27.1 and support for Kubernetes 1.31 to 1.35.
Three things are often confused, so it is worth separating them:
- It is the community ingress-nginx controller that is ending (a Kubernetes project), not NGINX as such, and not F5’s commercial NGINX Ingress Controller, which is a different product with different configuration.
- The Ingress API is not ending.
Ingressobjects in the cluster keep working, and the announcement explicitly allows moving to a different Ingress controller. As the modern replacement, however, the project recommends Gateway API. - Nothing switches itself off. That is exactly what makes the risk treacherous: traffic keeps flowing, there is just no one left to fix bugs.
The reach is huge. A joint statement by the Steering Committee and the Security Response Committee of 29 January 2026 states, citing internal Datadog research, that roughly 50% of cloud native environments rely on this tool. And it adds a sentence that defines the nature of the whole migration: none of the available alternatives is a direct “drop-in” replacement.
Why “it still works” is not enough
An ingress controller is an internet-facing component that is typically allowed to read Secrets across namespaces. The history of ingress-nginx shows how often serious bugs have appeared in it.
- March 2025: IngressNightmare. Wiz disclosed a set of four vulnerabilities (including CVE-2025-1974, CVSS 9.8) enabling unauthenticated remote code execution and cluster takeover. According to Wiz, about 43% of cloud environments were vulnerable and more than 6,500 clusters exposed the admission controller to the internet.
- March 2026: CVE-2026-4342. Five days before the archival, a configuration injection via a combination of annotations (CVSS 8.8) was disclosed, leading to code execution in the controller’s context and leakage of Secrets. It is fixed in v1.13.9, v1.14.5 and v1.15.1, the last releases that will ever ship.
- May 2026: CVE-2026-42945 (“NGINX Rift”). A heap overflow in the rewrite module of NGINX itself, rated CVSS v4 9.2 according to The Hacker News summary. NGINX Open Source 1.0.0 to 1.30.0 is affected; the fix is in versions 1.30.1 and 1.31.0.
The third item is the first real test of life “after end of support”. NGINX 1.27.1, which ships in ingress-nginx v1.15.1, falls within the affected range, and the archived project will not release a new version with a patched NGINX.
How much does NGINX Rift affect you?
Exploitation requires a specific configuration pattern: a rewrite directive followed by another rewrite, if or set directive, an unnamed PCRE capture group ($1, $2) and a question mark in the replacement string. So not every ingress-nginx deployment is exploitable. But you have to decide that yourself by inspecting the generated nginx.conf, because upstream will neither assess nor fix it for you.
On top of the technical risk there is an audit risk. Vulnerability management assumes that a discovered flaw has a path to remediation; for an archived project there is no such path, and the only answers left are a compensating control or replacing the component. More on the process in the article on vulnerability management.
Choosing a target: Gateway API or another Ingress controller
Gateway API is no longer an experiment. Version 1.5, released on 27 February 2026, moved ListenerSet, TLSRoute, the CORS filter for HTTPRoute and client certificate validation, among others, to the Standard channel. Version 1.6 of 30 June 2026 added TCPRoute and UDPRoute to the Standard channel. Many things that ingress-nginx handled with an annotation or ConfigMap now have a typed field in the API.
The current state of implementations is tracked in the official overview with conformance results. At the time of writing, those listed as conformant include Envoy Gateway, Cilium, NGINX Gateway Fabric, Traefik Proxy, Istio, kgateway and GKE; AWS Load Balancer Controller is listed as partially conformant.
| Option | When it makes sense | What to watch out for |
|---|---|---|
| Envoy Gateway, kgateway | Cluster without a service mesh; need for rate limiting, authentication and other policies beyond the standard | Extensions via custom CRDs are implementation-specific; only the Gateway API core is portable |
| Cilium | Cilium already runs in the cluster as the CNI | The gateway is tied to the CNI lifecycle; upgrading networking and ingress becomes a single operation |
| NGINX Gateway Fabric | The team wants to stay with NGINX as the data plane | Not a compatible successor; it does not take over ingress-nginx annotations |
| Istio | You already run or plan to run a mesh | Introducing a mesh just for ingress is unnecessary complexity |
| Managed cloud option | You want the provider to operate the data plane | Different pricing model, limits and partial conformance |
| Another Ingress controller | Dozens of teams, hundreds of Ingress objects, time pressure | Addresses the security risk, not the dependency on annotations; it only postpones the migration to Gateway API |
Azure (AKS)
If you use the managed NGINX in the application routing add-on, you have a hard deadline: according to the AKS documentation, Microsoft will stop supporting managed NGINX after November 2026, and migration to the Gateway API implementation or another supported implementation must be completed by November 2026. That is a few weeks away. The successor is the Gateway API implementation in the same add-on, built on an Istio control plane that manages only the infrastructure for Gateway API; the documentation describes it as the recommended default model for production, and from AKS 1.36 it is the default in new AKS Automatic clusters. Among the listed limitations: it offers no request header and body size limits, Lua scripts or rate limiting, and it cannot be enabled at the same time as the Istio service mesh add-on. The alternative is Application Gateway for Containers.
AWS (EKS)
Since 6 March 2026, AWS Load Balancer Controller has generally available Gateway API support: HTTPRoute and GRPCRoute on ALB, TCPRoute and UDPRoute on NLB. Instead of annotations, AWS specifics are configured via the LoadBalancerConfiguration, TargetGroupConfiguration and ListenerRuleConfiguration CRDs. Watch out for the architectural difference: ALB is not an in-cluster proxy, so both the cost model and the rule limits change.
When to stay with the Ingress API
A legitimate counter-argument: the Ingress API works, and a large migration under time pressure is a risk in itself. Traefik, for example, has a provider that reads many ingress-nginx annotations and targets exactly this scenario. It is a reasonable intermediate step, provided you call it that and verify that it covers your specific annotations. “Many” does not mean “all”.
Inventory: how much work it really is
The scope of the migration is determined not by the number of Ingress objects but by the number of distinct annotations and global settings. Start with three queries:
# 1. Is ingress-nginx running in the cluster? (command from the Kubernetes statement)
kubectl get pods --all-namespaces \
--selector app.kubernetes.io/name=ingress-nginx
# 2. Which annotations are used and how many times
kubectl get ingress -A -o json \
| jq -r '.items[].metadata.annotations // {} | keys[]' \
| grep nginx.ingress.kubernetes.io | sort | uniq -c | sort -rn
# 3. Global controller settings
kubectl get configmap -n ingress-nginx -o yaml
Sort the results into three groups:
- Has a standard equivalent: redirects, path rewrites, headers, CORS, backend TLS, weights.
- Handled by a specific implementation’s extensions: rate limiting, external authentication, timeouts, body size limits.
- Has no equivalent:
configuration-snippet,server-snippet, Lua. This is not translation but rewriting the intent, or moving the logic into the application.
The third group is the best predictor of effort.
The inventory should also cover everything that depends on ingress: cert-manager (issuers and solvers tied to Ingress), external-dns, WAF, dashboards and alerts built on NGINX metrics, the access log format, source IP preservation and allowlists on partners’ side.
Five behaviors that will not carry over on their own
The worst migration bugs do not come from the annotations you can see, but from default behavior nobody knows about. Kubernetes published a separate article on five surprising Ingress-NGINX behaviors:
- Regex paths are prefix matches and case-insensitive. A pattern that looks like an exact match also captures longer paths.
- The
use-regexannotation applies to all paths of the given host across all Ingress objects, not just the one where it is set. rewrite-targetimplies regex, with the same host-wide reach.- A request without a trailing slash gets a 301 redirect to the path with a slash if the rule is defined for a path ending in a slash.
- URLs are normalized before rules are evaluated.
Gateway API behaves more strictly and more predictably. After the switch, some traffic may therefore start getting 404s, or conversely a rule that unintentionally acted as protection may stop applying. For each host, list the actual paths from the access logs and turn them into a test suite.
ingress2gateway: a good start, not a finished migration
Ingress2Gateway 1.0 was released on 20 March 2026. While earlier versions handled three ingress-nginx annotations, version 1.0 covers more than 30 (CORS, backend TLS, regex, path rewrites and more). The project has integration tests that run the real Ingress-NGINX controller alongside several Gateway API implementations and compare runtime behavior, not just the YAML structure. Version 1.1 from April 2026 added the from-to-www-redirect, app-root and ssl-passthrough annotations (the latter is converted to TLSRoute); the current release is version 1.2.0 from July 2026.
# Convert all Ingress objects from a running cluster
ingress2gateway print --providers=ingress-nginx --all-namespaces > gwapi.yaml
# With a specific implementation's extensions
ingress2gateway print --providers=ingress-nginx \
--namespace my-api --emitter envoy-gateway > gwapi.yaml
The most valuable output is the warnings. The tool flags that it does not support configuration-snippet, that proxy-body-size has no equivalent in Gateway API and that URL normalization differs between implementations and cannot be set via the standard. The list of warnings is your real backlog.
Generated YAML is not a finished configuration
Treat the output as a draft for review. It does not resolve the split of responsibilities (who owns the Gateway and who owns the HTTPRoute), ReferenceGrants between namespaces, the cert-manager integration, or behavior that is not visible in the manifest at all. It belongs in the GitOps repository only after human review and after passing tests.
A zero-downtime migration plan
The principle is the same as for other changes in the traffic path: build the new controller next to the old one, verify it on real requests and move traffic gradually with the option of an immediate rollback. The Ingress2Gateway 1.0 announcement recommends the same approach: validation in a development cluster and gradual traffic shifting via weighted DNS, a cloud load balancer or traffic splitting.
- Install the Gateway API CRDs and the chosen controller alongside ingress-nginx. It gets its own LoadBalancer and its own IP address; existing traffic is unaffected.
- Create a Gateway and an HTTPRoute for a first, low-criticality service. Leave the old Ingress objects unchanged.
- Sort out TLS in advance. The certificate must be valid on the new Gateway before the first request reaches it. Watch out for ACME HTTP-01 challenges, which go wherever DNS points.
- Test against the new IP address with the set of paths from the access logs:
curl --resolve app.example.com:443:NEW_IP https://app.example.com/path. Compare status codes, redirects and headers, not just “it responds”. - Lower the DNS record TTLs well in advance (the AKS migration guide suggests 60 seconds).
- Switch over gradually with weighted DNS, or at the CDN or external load balancer level if you have one in front of the cluster. Monitor 4xx and 5xx error rates and latency against the pre-change baseline.
- Keep rollback to a single step: reverting the DNS record. That is why you should not delete the old controller straight away.
- Clean up only after things stabilize: delete the Ingress objects, IngressClass, admission webhook, Helm release and old dashboards.
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: api
namespace: my-api
spec:
parentRefs:
- name: public
namespace: gateway-system
hostnames: ["api.example.com"]
rules:
- matches:
- path: { type: PathPrefix, value: /v1 }
backendRefs:
- name: api-v1
port: 8080
Gradual switching has two weaknesses you need to plan for. Long-lived connections (WebSockets, gRPC streams) stay on the old controller until they close. And as long as both controllers run, there are two paths into the cluster, so security policies, WAF rules and network rules must apply to both. General principles of zero-downtime deployment are summarized in the article Kubernetes zero-downtime deployment.
If you cannot finish the migration by year-end
For large environments this is a realistic scenario. Then the goal is to reduce the attack surface and have the decision documented.
Interim measures for a running ingress-nginx
The last item is often overlooked. An unmaintained controller eventually becomes an obstacle to upgrading the cluster, so one debt turns into two. If you are planning an upgrade, handle ingress in the same plan (see Kubernetes upgrade).
There are also commercial extended-support offerings, or your own fork. A fork means taking over image builds and tracking CVEs in NGINX, OpenSSL, Lua modules and Go dependencies. It is a permanent commitment that needs to be costed soberly.
Key takeaways
- The project is closed. The ingress-nginx repository has been archived since 24 March 2026; the last release is v1.15.1 and there will be no more.
- The risk is no longer theoretical. CVE-2026-42945 in NGINX from May 2026 affects a version range that includes the bundled NGINX 1.27.1, and no upstream fix is coming.
- There is no drop-in replacement. The statement by the Kubernetes governing bodies says so directly. Plan for a project, not a Helm chart swap.
- Effort is driven by annotations and hidden behavior, not by the number of Ingress objects. The inventory is the first step and takes hours, not weeks.
- ingress2gateway speeds up the start, but its warnings are the list of work that remains for humans.
- Migrate in parallel and gradually. New controller next to the old one, testing against the new IP, switching via DNS, one-step rollback.
- On AKS with managed NGINX, the deadline is November 2026: after that, Microsoft will stop supporting it.
Sources
- Kubernetes SIG Network and Security Response Committee: Ingress NGINX Retirement: What You Need to Know (November 2025)
- Kubernetes Steering Committee and Security Response Committee: Ingress NGINX Statement (January 2026)
- GitHub: kubernetes/ingress-nginx, archived repository and versions table (March 2026)
- Wiz Research: CVE-2025-1974: The IngressNightmare in Kubernetes (March 2025)
- Kubernetes: CVE-2026-4342: ingress-nginx comment-based nginx configuration injection (March 2026)
- The Hacker News: 18-Year-Old NGINX Rewrite Module Flaw Enables Unauthenticated RCE (May 2026)
- Kubernetes: Before You Migrate: Five Surprising Ingress-NGINX Behaviors You Need to Know (February 2026)
- Kubernetes: Announcing Ingress2Gateway 1.0: Your Path to Gateway API (March 2026)
- Kubernetes: Gateway API v1.5: Moving features to Stable (April 2026) and Gateway API v1.6 (August 2026)
- Microsoft Learn: AKS Application Routing Add-On with the Kubernetes Gateway API (September 2026)