NGINX Ingress Controller 5.6 implements more support for configuring NGINX through resources instead of through snippets. HTTP Strict Transport Security (HSTS) becomes a first-class policy across VirtualServer, VirtualServerRoute, and Ingress. Two new annotations close configuration gaps for teams moving off Ingress-NGINX, and the X-Forwarded base headers can now be turned off through the ConfigMap.
Operational concerns got attention too. Startup is faster on large clusters, upstream services in another namespace keep their endpoints current, the Helm chart can declare a NetworkPolicy for you, and secret rotation reloads NGINX for every secret type rather than just TLS. Five of these changes came from our community, and each contributor is credited next to their work.
This release blog focuses on the new OSS features, but NGINX Ingress Controller 5.6 also includes some significant F5 integrations! For more info on these, read through our DevCentral release article here.
HSTS across VirtualServer, VirtualServerRoute, and Ingress
What’s new: HSTS is configurable natively on VirtualServer, VirtualServerRoute, and Ingress resources (nginx/kubernetes-ingress#10111).
Why it matters: HSTS tells a browser to reach your site over HTTPS and nothing else. Enforcing it used to mean a snippet, which your Kubernetes tooling cannot validate, so nothing catches a mistake in it before it reaches production. A first-class policy is reviewable, and it behaves the same way on every resource type you attach it to, so the Ingress your team ships this week and the VirtualServer it migrates to next quarter enforce the same thing.
Finer control over upstream headers and error pages
What’s new: Three changes give you more say over what NGINX Ingress Controller sends upstream and what it returns on an error, while improving Ingress-NGINX compatibility:
nginx.org/upstream-vhostsets the Host header sent upstream: It takes a fixed lowercase RFC 1123 subdomain and emits a warning event on the Ingress ifnginx.org/proxy-set-headersalso setsHost(nginx/kubernetes-ingress#10557).nginx.org/custom-http-errorsserves custom error pages: Responses in the configured status codes are passed to a named default backend instead of returned as-is (nginx/kubernetes-ingress#10423).disable-forwarded-headersturns the X-Forwarded base headers off: A ConfigMap value that stops NGINX Ingress Controller settingX-Forwarded-For,-Host,-Port, and-Protoon Ingress and VirtualServer resources. It defaults tofalse(nginx/kubernetes-ingress#10539).
Why it matters: The two annotations above help you migrate from Ingress-NGINX, and close some configuration gaps. Without upstream-vhost, a migrated application receives the controller’s internal host instead of the client-facing domain. The custom-http-errors annotation simplifies header handling and custom error pages. The ConfigMap switch answers a different question. Where a load balancer or CDN in front of NGINX Ingress Controller has already set the X-Forwarded headers, the controller was overwriting them, so your backend saw the controller rather than the original client.
Cross-namespace upstream services keep their endpoints current
What’s new: Upstream services in another namespace now receive endpoint updates (nginx/kubernetes-ingress#9676).
Why it matters: Cross-namespace backends used to go stale as pods came and went, so traffic kept being sent to endpoints that no longer existed. That surfaces as application errors, so you go looking at the application rather than at routing. If you split services across namespaces by team or tenant, this is worth the upgrade on its own.
A faster start when config safety is on
What’s new: With -enable-config-safety active, startup writes all configuration files first and runs a single nginx -t over the whole tree, instead of validating before writing each file. If that check fails, the controller works out which resources produced the invalid configuration, drops just those, and starts with the rest — the excluded resources are logged so you can see what did not load. On a test cluster with 250 Ingresses and 250 VirtualServers, startup went from 107 seconds to 6 seconds (nginx/kubernetes-ingress#10032).
Why it matters: The old implementation revalidated the whole configuration before writing each resource’s file, so startup cost grew with the square of the resource count — the bigger your cluster, the longer you waited. Batching keeps the safety check that config safety exists for, and a bad resource still cannot take the others down with it.
NetworkPolicy support in the Helm chart
What’s new: The chart takes a new controller.networkPolicy section: an enabled flag plus configurable ingress and egress rules, with schema validation and snapshot coverage. The podSelector derives from nginx-ingress.selectorLabels so it always targets the right controller pods, and policyTypes is generated from whichever rule sets you define. Developed by community contributor GabboPenna (nginx/kubernetes-ingress#8052), with a follow-up so helm upgrade --reuse-values works from a release that predates the template (nginx/kubernetes-ingress#10714).
Why it matters: Restricting what the controller pods can reach is a common requirement, and until now it meant keeping a NetworkPolicy manifest outside the chart and its selectors in step with whatever the chart rendered. Declaring it in values.yaml keeps the policy and the workload it protects together, and the selector cannot drift because the template derives it.
Secret rotation reloads NGINX for every secret type
What’s new: The -ssl-dynamic-reload optimization is narrowed to TLS server secrets, so rotating any other kind of secret reloads NGINX the way you would expect. Developed by community contributor dkulchinsky (nginx/kubernetes-ingress#10390).
Why it matters: The optimization only ever made sense for ssl_certificate, which NGINX can pick up at request time. Every other secret type is read when the configuration loads, so rotating a CA, JWK, htpasswd, OIDC, or API key secret quietly did nothing until some unrelated event forced a reload.
Smaller enhancements
- Error logs carry a
resource_namespaceattribute: One controller often serves many teams, and knowing which namespace an error came from saves debugging time (nginx/kubernetes-ingress#10373).
Stability and bug fixes
- Valid Ingress paths are accepted again: Path validation anchors each illegal keyword to a leading path segment, so
/variablesand/rootpageare valid. The regex matched/varand/rootanywhere in a path, turning ordinary application paths away as attempts to reach sensitive directories;/root/.sshand the rest stay blocked. Developed by community contributor hugolevino (nginx/kubernetes-ingress#10176). - No spurious secret warning for wildcard TLS users: The secret store lookup is skipped when an Ingress
tlsblock has nosecretName. That lookup can never succeed, and logged a misleading “secret doesn’t exist” warning on every sync — thousands per resync on a large multi-tenant cluster. Developed by community contributor rahulii (nginx/kubernetes-ingress#10543). - ExternalAuth sign-in redirects correctly: The
authSigninURIemitserror_page 401 = "..."as it should. (nginx/kubernetes-ingress#10594) 499is no longer accepted innginx.org/custom-http-errors: NGINX rejects the code, so allowing it failed an NGINX reload (nginx/kubernetes-ingress#10507).- Support for the NGINX Service Mesh integration is gone: If your deployment sets any of those flags or annotations, remove them before you upgrade to 5.6 (nginx/kubernetes-ingress#10432).
- [Enterprise only] Resource limits for the F5 WAF for NGINX v5 sidecars: The Helm chart takes a
resourcesblock for the enforcer and configManager containers, validated against the values schema. Before this, both ran with whatever the node would give them. Developed by community contributor jxn (nginx/kubernetes-ingress#9010).
Community recognition
From this release on, we’re crediting the community members who contribute to NGINX Ingress Controller, and naming their work where it lands. Whether you contributed code, helped shape a feature, or reported major bugs, thank you!
Community contributions
Five community members had work land in NGINX Ingress Controller 5.6: three bug fixes, NetworkPolicy support in the Helm chart, and resource limits for the WAF sidecars. Every one of them is credited above, next to the change they made. Thanks to dkulchinsky, GabboPenna, hugolevino, jxn, and rahulii. Your contributions in this release have helped shape NGINX Ingress Controller 5.6!
Want your name in NGINX Ingress Controller 5.7?
Pick up an open issue, contribute a feature you developed, or fix a bug you have run into. The contributing guide covers how to get started, from opening a discussion to sending your first pull request.
Head over to the GitHub release page for the full changelog, and the NGINX Ingress Controller docs when you’re ready to upgrade to 5.6. If you’re moving over from Ingress-NGINX, the Kubernetes NGINX landing page covers the migration. For more information on the enterprise level features included in this release, check out our DevCentral article here.
We’re proud of what the team and the community built here, and we hope it makes your clusters easier to run.


