Six months ago, in March 2026, the most widely deployed Kubernetes ingress controller stopped receiving patches. Not deprecated, not maintenance mode — done. Kubernetes SIG Network and the Security Response Committee announced in November 2025 that Ingress NGINX would get best-effort maintenance until March 2026 and then nothing: no releases, no bugfixes, no security updates. Every cluster still routing edge traffic through it today is running an unmaintained proxy at the exact layer where the last big lesson — IngressNightmare, an unauthenticated remote-code-execution chain disclosed in March 2025 — cost a CVSS 9.8.
The good news is that the replacement stopped being a stopgap in the same window. Gateway API v1.5, released February 27, 2026, promoted six long-awaited features to the Standard channel — including stable TLSRoute, ListenerSet, and a native HTTPRoute CORS filter — and v1.6 followed on June 30 by graduating TCPRoute and UDPRoute. The gaps that used to force NGINX-specific annotations or a custom sidecar are now stable, conformance-tested APIs. This post maps each common annotation workaround to its stable replacement, lays out the now-mostly-mechanical migration path, and picks a default Gateway API implementation for a self-hosted fleet running on owned hardware.
The deadline already passed
The retirement notice, published November 11, 2025 during KubeCon North America in Atlanta, is unusually blunt for the Kubernetes project. Best-effort maintenance until March 2026; afterward, "no further releases, no bugfixes, and no updates to resolve any security vulnerabilities." Existing deployments keep functioning and installation artifacts remain available — your Ingress objects will not stop routing tomorrow — but the next vulnerability disclosure gets no fix, ever.
The cause was not a technical verdict on NGINX. It was maintainership collapse: for years the project ran on one or two people doing development in their spare time, and even the 2024 announcement of a planned successor (InGate, to be built with the Gateway API community) failed to attract new maintainers. InGate never matured and is being retired alongside its parent. SIG Network and the SRC recommend that all users "begin migration to Gateway API or another Ingress controller immediately."
The cost of ignoring that recommendation has a name and a number. On March 24, 2025, Wiz researchers disclosed IngressNightmare: CVE-2025-1974 (CVSS 9.8, unauthenticated RCE through the admission webhook) chained with three config-injection flaws (CVE-2025-1097, CVE-2025-1098, CVE-2025-24514, each 8.8), letting an attacker with pod-network access inject arbitrary NGINX configuration, read every secret in every namespace, and take over the cluster. The root cause was architectural — an unauthenticated admission controller that renders attacker-influenced input into NGINX config — not a typo. The next flaw of that shape, in a controller nobody patches, is a permanent zero-day on your edge.
The v1.5 payoff table: every annotation workaround, now a stable API
For years the honest objection to migrating was the feature gap: production Ingress NGINX setups lean on dozens of nginx.ingress.kubernetes.io/* annotations, and early Gateway API had no stable equivalent for several of them. Gateway API v1.5 (released February 27, 2026, announced April 21) closed that gap by promoting six features to the Standard (GA) channel. Here is what each one replaces:
| What you hacked with NGINX annotations | Now stable in Gateway API v1.5 | Why stable matters |
|---|---|---|
ssl-passthrough plus stream-snippet SNI tricks to pass TLS through to backends | TLSRoute v1 (GEP-2643) | SNI-based L4 routing is a versioned API with conformance coverage instead of a boolean annotation whose semantics differ per controller version |
One copy-pasted Gateway object per team, or shared-Gateway merge fights | ListenerSet (GEP-1713) | Teams attach their own listeners to a shared Gateway; listener ownership is declarative instead of a merge convention the platform team polices by hand |
enable-cors plus a dozen cors-* annotations (origins, methods, headers, max-age) | HTTPRoute CORS filter (GEP-1767) | Cross-origin policy is route config the data plane enforces, portable across implementations instead of NGINX-only annotation strings |
auth-tls-* annotation soup for client-certificate / mTLS verification | Gateway client certificate validation (GEP-91, GEP-3567) | mTLS verification moves from annotation folklore to a specified API with defined validation behavior |
| Cross-namespace backend references with no trust model (or out-of-band convention) | ReferenceGrant v1 | The cross-namespace trust grant — "namespace B may route to my Service" — is GA, cementing the security story the whole route model depends on |
| Hand-picked certs for Gateway-originated upstream TLS | Certificate selection for TLS origination (GEP-3155) | Which certificate the Gateway presents upstream is explicit config, not implementation default behavior |
And the window kept moving: Gateway API v1.6 (shipped June 30, 2026) graduated TCPRoute and UDPRoute to v1 on the Standard channel and deprecated their v1alpha2 shapes, so L4 routing for non-HTTP workloads no longer sits on an alpha API either. If your migration plan stalled in 2024 on "TLSRoute is alpha," that excuse has expired twice over.
Why Gateway API, not just another Ingress controller
Switching from Ingress NGINX to a maintained Ingress controller fixes the patching problem but re-buys the structural one: the Ingress API is HTTP-only and effectively frozen, so every feature beyond basic host/path routing arrives as a vendor-specific annotation with no portability and no conformance suite.
Gateway API inverts that. Infrastructure owners manage GatewayClass and Gateway (listeners, TLS mode, addresses) while developers own HTTPRoute/TLSRoute/TCPRoute attachments; traffic splitting, header matching, and filters are first-class fields; and implementations prove behavior against shared conformance profiles (the v1.6 suite now requires the GATEWAY-TCP and GATEWAY-UDP profiles, not just e2e spot checks). A route written against the Standard channel survives swapping the data plane underneath it — which is exactly the migration you are doing now, and exactly the one you never want to redo by hand again.
The migration is mechanical now
The tooling caught up with the API. Ingress2Gateway 1.0 (March 2026) expanded Ingress-NGINX annotation support from three annotations to more than thirty — CORS, backend TLS, regex matching, path rewrites — translating existing Ingress manifests plus annotations into Gateway + HTTPRoute YAML while warning about anything it cannot translate:
go install github.com/kubernetes-sigs/ingress2gateway@latest
ingress2gateway print --providers=ingress-nginx --input-file my-ingress.yamlThe recommended cutover avoids a flag day: install the chosen Gateway API implementation alongside Ingress NGINX, generate and review the translated routes, shift traffic gradually (DNS weight or a parallel front IP), and keep NGINX serving until the new data path is verified under real load. TLS automation ports cleanly — cert-manager ships a GA Gateway shim alongside its Ingress shim, so certificate issuance follows the same ClusterIssuer setup.
Be honest about the non-mechanical remainder, because it is where migrations stall. Anything living in configuration-snippet, server-snippet, or embedded Lua does not translate — ingress2gateway will flag it, but reimplementing custom auth logic, exotic regex rewrites, or bespoke buffering behavior as Gateway API filters (or an implementation extension) is real engineering. The correct first step is an annotation inventory: most fleets discover that 80% of their annotations are CORS, rewrites, and TLS settings that now map one-to-one onto stable fields, and the remaining 20% is a short, named list of snippets to rewrite deliberately. That list is the actual migration scope — everything else is codegen.
Which implementation for owned hardware
For a self-hosted fleet on bare metal or rented dedicated servers — no cloud load-balancer controller to lean on — the choice comes down to four serious options:
| Implementation | Data plane | Why pick it | Why not |
|---|---|---|---|
| Envoy Gateway (default) | Envoy | CNCF project, maximum portability, strongest conformance story; ~325k qps in gateway-api-bench per Gardener's published comparison | Slightly slower config-update propagation than the eBPF options; another control plane to operate |
| Cilium Gateway | eBPF / Envoy | Fastest update times alongside Istio/Kong; zero extra proxy hop if Cilium is already your CNI | Requires adopting Cilium as your CNI — a non-starter if you are on Calico/flannel and staying there |
| NGINX Gateway Fabric | NGINX | Smallest mental-model jump for an NGINX shop; F5-backed | Youngest implementation, weakest throughput in the field (~91k qps, second-slowest measured) |
| Traefik / kgateway | Traefik / Envoy | Traefik's Gateway provider is production-ready since v3.1 — the easy path if Traefik already terminates your edge | Smaller Gateway API conformance surface than the purpose-built options; evaluate against the profiles you need |
The default recommendation is Envoy Gateway: it is the portable, vendor-neutral pick whose routes you can later move to any other conformant implementation — the entire point of migrating to a standard API. Deviate to Cilium when the fleet already runs Cilium networking, to NGINX Gateway Fabric when operator familiarity outweighs throughput headroom, and stay on Traefik's Gateway provider when Traefik is already your edge and its supported profile set covers your routes. Whichever you choose, verify against the published conformance reports for the profiles you need rather than the marketing matrix.
Migrate on your timeline, not the CVE's
The retirement deal is unusually forgiving as these things go: nothing breaks on its own, artifacts stay published, and the migration tooling is the best it has ever been. What you no longer get is the one thing an edge proxy exists to provide — a patched data path the next time someone finds an admission-controller-shaped hole in it. With TLSRoute, ListenerSet, CORS, client-cert validation, and ReferenceGrant all Standard, plus TCP/UDP routes graduated in v1.6 and thirty-plus annotations machine-translatable, "the successor isn't ready" stopped being true around February. The remaining work is an annotation inventory and a side-by-side cutover — weekend-sized for a small fleet, and strictly smaller than incident response on an unpatchable edge.
Bex.co is the open-source, AI-native Render alternative — push a git repo, get a running HTTPS service on machines you own. Star the repo on GitHub or deploy your first app today.



