The kubernetes/ingress-nginx repository is archived. Read-only. The controller's last release, controller-v1.15.1, was published on 19 March: 187 days ago. This is not a project that quietly faded out — it was retired on purpose, with a date and a statement — and what the Kubernetes Steering Committee and Security Response Committee signed to explain it was not a security flaw. It was a sentence about staffing: "maintained solely by one or two people working in their free time".
Three dates and two sentences
On 11 November 2025 the Kubernetes blog announced the retirement for March 2026. On 29 January 2026 the two committees published a joint statement to, in their words, "reinforce the scale of this change". And in March it closed: the repository was archived read-only. That is the official record; we checked it today against the GitHub API, which returns "archived": true, a last push dated 23 March 2026 and three controller releases published on 19 March — controller-v1.15.1, controller-v1.14.5 and controller-v1.13.9, with their three matching Helm charts — the last ones that will ever exist. The project has 19,469 stars.
The two sentences that matter in the statement are these. The first sets the scope: Ingress NGINX is "a piece of critical infrastructure for about half of cloud native environments", and further down they put a number on it while naming the source — "According to internal Datadog research, about 50% of cloud native environments currently rely on this tool". That is a third party's internal research quoted by Kubernetes, not a census; we take it for what it is, an order of magnitude. The second sentence admits no nuance: "There will be no more releases for bug fixes, security patches, or any updates of any kind after the project is retired". And the committee closes without diplomacy: "choosing to remain with Ingress NGINX after its retirement leaves you and your users vulnerable to attack".
The number to watch was never a CVE
This is where the case parts company with the rest. A vendor running late with a patch is a scheduling problem. A project that shuts down because it never had people is something else, and the statement says so plainly: there were "years of public warnings that the project was in dire need of contributors and maintainers". Years. The warning had been given and had nowhere to land, because that component was on nobody's record: nobody bought it, nobody signed anything for it, and so nobody ever had to answer the question that predicted the whole thing — how many people are behind it, and are any of them paid to be there.
It is worth saying what this is not, because the easy headline is right there. It is not an argument against open source: our own infrastructure is open source almost top to bottom — Proxmox VE, Ceph, Zabbix, WireGuard, Docker Swarm and Kubernetes — and we are not about to change that. It is an argument for looking at who maintains each critical dependency, which is a licence-neutral question. Paid software has its exact version of the same problem: it is called end of support, and the box sits just as still. We already wrote it about another ecosystem with the same governance hole: who maintains your website is a question with a name attached, or it is not a question at all. And when the answer is "nobody", sometimes there is simply nothing to patch.
The most uncomfortable part of the statement is the one describing the silence: "Existing deployments will continue to work, so unless you proactively check, you may not know you are affected until you are compromised". Nothing falls over. No dashboard turns red. The statement itself gives the command to settle it, and it is one line:
kubectl get pods --all-namespaces \
--selector app.kubernetes.io/name=ingress-nginx
Translating the YAML is the easy part
On 20 March, three days before the repository was archived, SIG Network released Ingress2Gateway 1.0, the tool that translates Ingress resources into Gateway API. That release's jump measures the problem: it used to support three Ingress-NGINX annotations; 1.0 supports more than thirty. The announcement's authors are explicit about what it is not: "Ingress2Gateway is a migration assistant, not a one-shot replacement" and "Migration is not a "one-click" affair".
The tool warns in writing about what it cannot translate, and those warnings are the list of decisions somebody will have to make by hand. Three examples from the announcement itself: the configuration-snippet annotation is unsupported; proxy-body-size has no Gateway API equivalent and goes untranslated; and URL normalization cannot be configured in Gateway API — "Gateway API does not support configuring URL normalization (RFC 3986, Section 6)". What the tool cannot warn you about is the opposite case: what it translates too faithfully, because the original did something you did not know it did.
Five things your routing does that nobody chose
In February, Steven Jin (Microsoft) published a pre-migration article on the Kubernetes blog listing five default Ingress-NGINX behaviours. We summarise them because they are, in our view, the expensive part of this move:
| Default behaviour | What it means in your cluster |
|---|---|
| A regex pattern matches by prefix and is case-insensitive | The path /[A-Z]{3} lets /uuid through |
use-regex is not per-Ingress | It applies to every path of that host across all Ingresses: one team changes another team's routing |
rewrite-target implies regex | You turn on regex mode without having asked for it |
| Missing trailing slash | Returns a 301 to the path with the slash, even when pathType is Exact |
| It normalizes the URL before matching rules | /ip/abc/../../uuid reaches /uuid; ////uuid answers 301 |
Our reading, stated as opinion: the first and last items on that list are not routing details, they are access control. If somebody wrote a rule three years ago believing it restricted traffic to three capital letters, it has restricted nothing for three years. No scanner and no YAML audit will find that rule: it only surfaces when somebody translates the file into another language and has to say out loud what they meant. Which is why this migration is not a translation, it is a reading.
In the destination's favour: on URL normalization, the same article says most Gateway API implementations already strip . and .. segments by default, naming Istio, Envoy Gateway and Kgateway. So the risk is less about losing normalization than about not knowing your application had been leaning on it for years.
Do not translate: measure first
Swapping a cluster's ingress controller is, in the classification that actually matters, a manual configuration change in production. And there is literature on that: the Oppenheimer, Ganapathi and Patterson study presented at USENIX in 2003 on why internet services fail put operator configuration changes at the top of the causes of serious outages, with hardware explaining only 10 to 25 %. Twenty-three years later we still see the same thing on call. The difference between a fault and an outage is not set by the component: it is set by the procedure you touch it with.
Here is how we approach it. First, the real inventory is not in the YAML but in the ingress's own access log: hosts, paths and response codes over a couple of weeks, which is the only list of what anybody actually uses. Second, translate and read every warning, because an "unsupported" is a product decision dressed up as a caution. Third, bring the new controller up in parallel and compare behaviour against real traffic before touching DNS: same paths, same codes, same redirects. And fourth, cut over with a rollback that is prepared and rehearsed, not "documented". It is the same discipline of reproducible, reversible deployments we apply to everything else, and which we already described when we wrote that "latest" is not a version.
The calendar nobody budgeted for
This does not end with the ingress, and that is the point a lot of management misses when they approve a Kubernetes project. The project's support policy is public and written on its releases page: "the Kubernetes Community will support active patch release series for a period of roughly fourteen (14) months" — twelve months of standard support plus two in maintenance mode for critical fixes only. With three minor releases a year, today's calendar looks like this:
| Version | End of standard support | End of life |
|---|---|---|
| 1.34 | 27-08-2026 | 27-10-2026 |
| 1.35 | 28-12-2026 | 28-02-2027 |
| 1.36 | 28-04-2027 | 28-06-2027 |
| 1.37 | 28-08-2027 | 28-10-2027 |
Read plainly: if you are on 1.34 today, you have until 27 October. And when you reach 1.37 you will have another date. The cost of Kubernetes is not the cluster, it is the calendar: a major upgrade every few months, forever, plus the separate calendar of every ecosystem piece around it — and nobody signs that second one. Ingress NGINX is exactly that: a date that was on no roadmap and turned up anyway.
And now the part that works against us, since we offer managed Kubernetes: not everyone needs Kubernetes. We run Kubernetes clusters and Docker Swarm clusters, and we choose per case, not per whatever looks better in a proposal. If your product is four services and a database, with a team that has nobody dedicated to platform work, the calendar above will be eaten by somebody who should be writing product. That conversation is cheaper had early than late.
What we would do this week
- Check whether it applies to you, with the statement's command and with
kubectl get ingressclass. On third-party managed clusters, also ask which controller the provider installed: this usually arrived via a chart nobody remembers choosing. - Measure the real size of the migration, which is not the number of Ingresses but the number of distinct annotations you use. This one line answers it in ten seconds:
kubectl get ingress -A -o json \
| jq -r '.items[].metadata.annotations // {} | keys[]' \
| grep '^nginx.ingress.kubernetes.io/' \
| sort | uniq -c | sort -rn
- Pull the real list of host + path + status code from the access log for the last fourteen days. That list is the migration's acceptance criterion; without it, "it works" means "I opened the home page and it loaded".
- Translate with Ingress2Gateway and read the warnings one by one. Each "unsupported" is a capability you have today and will not have tomorrow, and somebody has to decide whether that matters. The tool does not decide it.
- And the non-technical one: add a line to each critical dependency's record with how many people maintain it and whether anyone is paid to. It is a two-minute question that in this case had been answered in public for years — the statement itself speaks of "years of public warnings" — and it would have bought lead time instead of two months.
What this case leaves us: for years, the governance question everyone asked about a dependency was "does it have open CVEs?". It turns out the one that predicted the closing of half an ecosystem's front door appeared in no scanner, was answered out loud by the maintainers themselves, and was about staffing. It was published. Nobody read it because that component belonged to nobody.
Do you know who maintains the thing that publishes your product?
We run Kubernetes and Docker Swarm in production, our own and our clients', with reproducible deployments and a rehearsed rollback. In the infrastructure and cloud we manage, every critical piece has a pinned version, an owner and a known expiry date; and if what you need is to decide whether Kubernetes suits you at all, that is consulting and we do it without selling anybody's licences. If your answer to the title's question is "I think so", it is a no.
Talk to everyWANNote on sources
All consulted on 22 September 2026. One: the joint statement from the Kubernetes Steering Committee and the Security Response Committee, published on the Kubernetes blog on 29 January 2026, source of the verbatim quotes that open it: the "about half of cloud native environments" scope, the attribution of the 50 % figure to internal Datadog research, the "one or two people working in their free time" sentence, the one about no further releases or patches, the warning that staying exposes you to attack, the one about silence until compromise, and the check command. Two: the retirement announcement of 11 November 2025, also on the Kubernetes blog, which sets March 2026 and recommends migrating to Gateway API or another controller. Three: GitHub's public API for kubernetes/ingress-nginx, queried today: archived true, pushed_at of 23 March 2026, the three release tags published on 19 March 2026, and the star count. The 187 days are ours, subtracting calendar dates between 19 March and today. Four: "Announcing Ingress2Gateway 1.0", Kubernetes blog, 20 March 2026 (Beka Modebadze, Google, and Steven Jin, Microsoft): the jump from three to more than thirty annotations, the two sentences about it not being a one-click replacement, and the warnings about configuration-snippet, proxy-body-size and URL normalization. Five: "Before You Migrate: Five Surprising Ingress-NGINX Behaviors You Need to Know", Kubernetes blog, 27 February 2026 (Steven Jin, Microsoft): the five behaviours in the table and the note that Istio, Envoy Gateway and Kgateway normalize by default. Six: kubernetes.io's patch releases page, source of the fourteen-month support quote — twelve standard plus two in maintenance — and the 1.34 to 1.37 dates. Seven: Oppenheimer, Ganapathi and Patterson, "Why Do Internet Services Fail, and What Can Be Done About It?", USENIX 2003, for the leading cause of serious outages. What we are not claiming: we have not audited the Ingress-NGINX code nor reproduced the five behaviours on a cluster of our own — we take them from the cited source; we have no figure of our own for how many clusters still use it; we do not claim any unpatched vulnerability exists in it today, only that if one appears there will be no patch; and we do not recommend any specific Gateway API implementation here because the choice depends on what else runs in that cluster. Our opinion: that the useful question about a dependency is about staffing rather than CVEs, that this migration is a reading of your routing rather than a translation, that items one and five in the table are access control, the measure-before-you-translate method, and that there are cases where Kubernetes does not pay off.
Cover image: public domain photograph of a bank of access turnstiles, cropped by us. The text and branding are ours, added on top.