In November 2025, Kubernetes pulled the rug out from under the most popular way to route traffic into a cluster: the ingress-nginx controller was retired, with maintenance halting in March 2026 and no security patches after that. If you run a platform, that announcement forced a migration question on someone else's timetable. But there is a second, harder question nobody forces on you — and it matters more for a new cluster: is the Gateway API, the official successor to Ingress, finally complete enough to build a git-push PaaS's custom-domain and TLS routing on from day one?
As of Gateway API v1.5 — released February 27, 2026 and announced April 21, 2026 as the project's biggest release yet — the answer is yes, with three exceptions. Here is the verdict up front, with the evidence below.
| PaaS routing need | v1.5 Standard-channel answer | Status |
|---|---|---|
| Custom-domain HTTP routing per app | HTTPRoute (GA since v1.0, Oct 2023) | Standard, boring, good |
| Shared wildcard TLS termination | Gateway HTTPS listener + cert-manager Certificate | Standard |
| Per-team listeners on one shared Gateway | ListenerSet | New in v1.5 Standard |
| SNI passthrough for tenant-held TLS | TLSRoute (Passthrough and Terminate modes) | New in v1.5 Standard |
| Cross-namespace route grants | ReferenceGrant, now v1 | New in v1.5 Standard |
| Frontend mTLS for internal tenants | Gateway client-certificate validation | New in v1.5 Standard |
| Gateway-to-backend mTLS origination | tls.backend.clientCertificateRef on Gateway | New in v1.5 Standard |
| Browser CORS for preview apps | HTTPRoute CORS filter | New in v1.5 Standard (nice-to-have, not blocking) |
| Raw TCP/UDP (databases, game servers) | TCPRoute / UDPRoute | Experimental until v1.6 (Aug 2026) |
| Backend TLS policy attachment | BackendTLSPolicy | Still experimental |
| Sticky sessions | SessionPersistence | Still experimental |
Translation: every HTTP workload a git-push PaaS serves — custom domains, automatic TLS, multi-tenant listeners, SNI passthrough — now has a Standard-channel API behind it. The three remaining gaps only bite if you route raw TCP/UDP, need sticky sessions, or configure backend TLS via policy attachment. If that is not your Day-1 workload, build new clusters on Gateway API now; keep existing Ingress fleets on their own migration schedule.
What v1.5 actually graduated, in PaaS terms
Gateway API ships two channels: Experimental, where new APIs incubate, and Standard, the GA contract with no breaking changes. v1.5's entire theme was graduation — six widely-requested features moved from Experimental to Standard. Each one closes a specific hole a platform team would otherwise have hit:
ListenerSet (GEP-1713) — the multi-tenancy unlock. Before v1.5, every listener had to be declared inline on the Gateway object, which meant the platform team owned a single shared resource that every tenant's hostname change touched. ListenerSet lets listeners live in tenant namespaces and merge onto a target Gateway, and lifts the practical ceiling past 64 listeners on one shared Gateway. For a PaaS, this is the difference between "one Gateway per tenant" sprawl and a single edge Gateway with per-team listener delegation. This was the single biggest Day-1 blocker v1.5 removed.
TLSRoute (GEP-2643) — SNI routing as a stable API. TLSRoute matches the Server Name Indication from the TLS handshake and routes the stream to backends, in either Passthrough mode (the Gateway never sees keys or plaintext — end-to-end encryption to the tenant) or Terminate mode (centralized cert management at the Gateway, plaintext TCP upstream). Passthrough is what lets tenants bring certificates the platform never holds. Note the version boundary: TLSRoute graduated as v1, and the old v1alpha2 is not in the v1.5 Standard install YAMLs — plus its CEL validation requires Kubernetes 1.31 or newer, though Gateway API itself only needs 1.30+.
ReferenceGrant to v1 — the boring one that matters. Cross-namespace references (an HTTPRoute in a tenant namespace pointing at a Gateway in infra, a backend in another namespace) require a ReferenceGrant. It had not changed in over a year, so v1.5 stamped it v1 under the GA no-breaking-changes contract. Multi-tenant routing without it is impossible; now it is stable.
Frontend mTLS (GEP-91) — client-certificate validation. Gateways can now validate client certificates against CA bundles (frontendValidation, with AllowValidOnly and AllowInsecureFallback modes, configurable globally or per port). Most public PaaS workloads will never touch this, but internal platforms serving machine tenants over mTLS get it as a stable API instead of controller-specific annotations.
Backend mTLS origination (GEP-3155) — Gateway as TLS client. tls.backend.clientCertificateRef configures the client certificate the Gateway presents to backends, Gateway-wide. Be precise here, because the names invite confusion: this Gateway-level origination field is what graduated. BackendTLSPolicy — the separate policy-attachment API for configuring TLS to backends — remains experimental. If your backend-TLS story is "terminate at the edge, plaintext inside the cluster," neither matters on Day 1; if it is "mTLS everywhere," you now have stable origination with policy attachment still incubating.
HTTPRoute CORS filter (GEP-1767) — genuinely non-blocking. CORS as a native route filter (allowOrigins, allowMethods, allowHeaders, exposeHeaders, allowCredentials, maxAge) is convenient for preview apps and browser-heavy tenants. It never blocked a PaaS routing layer — you could always set headers upstream — so treat it as a bonus, not a reason.
Two process notes round out the release: the project moved to a release-train model (features ship when ready on a fixed cadence, docs included or the feature does not ship), and seven implementations were already fully conformant with v1.5 at announcement — Agentgateway, Airlock Microgateway, GKE Gateway, HAProxy Ingress, kgateway, NGINX Gateway Fabric, and Traefik Proxy. A conformance suite you can point at is itself a maturity signal Ingress never had.
The Day-1 sketch: custom domains and TLS on a shared Gateway
Concretely, here is what the PaaS edge looks like on v1.5 Standard — one platform-owned Gateway, per-team listeners, per-app routes, cert-manager filling in the Secrets:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: paas-edge
namespace: infra
spec:
gatewayClassName: kgateway # envoy, cilium, traefik... pick a v1.5-conformant one
listeners:
- name: http
protocol: HTTP
port: 80
allowedRoutes:
namespaces:
from: All
- name: https
protocol: HTTPS
port: 443
hostname: "*.apps.example.com"
tls:
certificateRefs:
- name: wildcard-apps-cert # filled by cert-manager
allowedRoutes:
namespaces:
from: AllThe team's own listeners live in the tenant namespace and merge onto the shared Gateway — no platform-team ticket required:
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: team-acme-listeners
namespace: team-acme
spec:
parentRef:
name: paas-edge
namespace: infra
listeners:
- name: https-acme
protocol: HTTPS
port: 443
hostname: acme.example.com
tls:
certificateRefs:
- name: acme-cert # the team's own cert-manager CertificateAnd each app gets its own route attached to its team's listener:
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: acme-app
namespace: team-acme
spec:
parentRefs:
- name: paas-edge
namespace: infra
sectionName: https-acme
hostnames:
- acme.example.com
rules:
- backendRefs:
- name: acme-web
port: 8080Three things to notice. First, the platform team touches the Gateway once; tenants self-serve listeners and routes in their own namespaces — the ListenerSet graduation is what makes this delegation a stable API rather than an experiment. Second, TLS issuance is unchanged from the Ingress world: cert-manager's ACME HTTPRoute solver creates a temporary HTTPRoute for the challenge and updates the listener's Secret, so the kubectl apply muscle memory around Certificates carries over. Third, nothing in this sketch needs the Experimental channel — that is the v1.5 punchline.
The three honest gaps (and the migration gotchas)
A green light with exceptions is only useful if the exceptions are named precisely. Here they are:
1. Raw TCP/UDP routing. If your PaaS exposes databases, game servers, or anything else that is not HTTP or TLS-SNI-routable, you need TCPRoute or UDPRoute — and those stayed experimental in v1.5. The wait was short: v1.6 (August 2026) graduated both to Standard. So the rule is simple: HTTP workloads build today; if TCP/UDP exposure is a Day-1 requirement, install the Experimental channel deliberately or keep those listeners on Ingress until you pick up v1.6.
2. Sticky sessions. Session persistence (session affinity beyond what a Service's sessionAffinity gives you) is still an experimental API — v1.6 development even removed its idleTimeout field, a sign it is still being shaped. Most twelve-factor apps on a PaaS do not need it; if yours does (legacy stateful web apps, some game backends), verify your chosen implementation's support before committing, because Standard-channel Gateway API will not promise it to you yet.
3. BackendTLSPolicy. As noted above: Gateway-level mTLS origination is stable, but the BackendTLSPolicy attachment API is not. v1.6 started letting it combine with other route types, which shows where it is headed, but on v1.5 it is experimental. Clusters that terminate TLS at the edge and run plaintext internally — the PaaS default — are unaffected.
Then the two migration gotchas that bite brownfield clusters, not greenfield ones. First, installing the v1.5 Standard CRDs over a v1.4-or-earlier Experimental install orphans your existing Experimental TLSRoutes: v1alpha2 is not in the Standard YAMLs, so those objects stop working until you migrate them to v1. Either stay on Experimental through the upgrade or convert first — do not discover this in production. Second, per-team certificate self-service (each tenant minting certs for its own listeners on a shared Gateway) was the exact hole cert-manager called out when ingress-nginx retired; its fix rides the ListenerSet lineage, with experimental support landing around cert-manager 1.20 (February 2026). Confirm your cert-manager version handles Gateway + ListenerSet before you promise tenants self-serve TLS.
New cluster versus existing fleet: the decision
| Situation | Verdict |
|---|---|
| New cluster, HTTP workloads with custom domains + auto TLS | Build on Gateway API now (v1.5+ Standard, conformant implementation, K8s 1.30+; 1.31+ if you use TLSRoute) |
| New cluster that must expose raw TCP/UDP on Day 1 | Gateway API with eyes open: take v1.6+ for stable TCPRoute/UDPRoute, or keep those listeners on Ingress |
| Existing Ingress fleet (not ingress-nginx) that works | No forced move. Migrate on your schedule with ingress2gateway 1.0 (released March 2026), which converts Ingress resources plus nginx annotations automatically |
| Existing ingress-nginx fleet | That migration is overdue, not optional — maintenance ended March 2026 with no further security patches. Gateway API is the community-endorsed destination, but another maintained Ingress controller also stops the bleeding |
| Workloads needing sticky sessions or BackendTLSPolicy | Keep those specific listeners where they are; move everything else |
Note what is deliberately absent from the table: a "wait for more graduations" row for standard HTTP PaaS workloads. There is no genuinely blocking gap left for those — waiting just defers the learning curve while the ecosystem (seven conformant implementations, a release train, ingress2gateway 1.0) compounds around Gateway API.
What this means going forward
v1.5's release-train process matters more than any single graduation: features now ship on cadence with docs as a merge requirement, and v1.6 already delivered TCPRoute and UDPRoute two quarters later. The direction is one-directional — Ingress is in maintenance mode conceptually (the API is not disappearing, but no new routing expressiveness will ever land there), while every new capability lands in Gateway API. Building Day-1 routing on Ingress in late 2026 means building on an API whose future is frozen.
The practical takeaway for a git-push PaaS: the routing layer is three Kubernetes objects — a platform-owned Gateway, tenant-owned ListenerSets, and app-owned HTTPRoutes — with TLS issuance from cert-manager exactly as before and RBAC boundaries that finally match team boundaries. That is a smaller, more legible contract than any annotation-driven Ingress setup, and as of v1.5 it is all Standard channel. Ship the new cluster on it.
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.
Sources
- Kubernetes Blog, "Gateway API v1.5: Moving features to Stable" (April 21, 2026; release February 27, 2026; v1.5.1 patch) — the six Standard-channel promotions, release-train model, conformant implementations, K8s 1.30+ floor.
- Gateway API v1.5.0 release notes (kubernetes-sigs/gateway-api) — TLSRoute graduation to
v1,v1alpha2removal from Standard YAMLs, CEL validation requiring K8s 1.31+. - Kubernetes Blog, "Gateway API v1.6: TCPRoute and UDPRoute Graduate to Standard" (August 3, 2026).
- Kubernetes Blog, "Ingress NGINX Retirement: What You Need to Know" (November 11, 2025) — maintenance halt March 2026, migrate to Gateway API or another controller.
- cert-manager announcement on ingress-nginx EOL and Gateway API (November 2025) — XListenerSet/ListenerSet as the per-team TLS self-service path, experimental support targeted in 1.20.
- DevOps.dev, "From Ingress to Gateway API: A Hands-On Migration with ingress2gateway 1.0 on kind" (March 2026).
- GKE docs, "Migrate Ingress to Gateway API"; CNCF webinar on zero-downtime ingress-nginx to Envoy Gateway migration.



