NGINX
Ingress Controller
Nginx version
Kubernetes
Security

NGINX Ingress Controller hide Nginx version

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

Introduction

If you want the NGINX Ingress Controller to stop exposing the full NGINX version string, the usual setting is server_tokens off. In the Kubernetes ingress-nginx controller, that is typically configured through the controller ConfigMap. The important nuance is that hiding the version is not the same as hiding the entire Server header.

What server_tokens Actually Changes

In plain NGINX, server_tokens off; removes the detailed version number from responses and many error pages. Instead of a header like Server: nginx/1.25.x, you usually get a simpler Server: nginx.

That means this setting helps reduce version disclosure, but it does not make NGINX invisible.

Configure It in ingress-nginx

For the common ingress-nginx controller, set server-tokens in the controller ConfigMap.

yaml
1apiVersion: v1
2kind: ConfigMap
3metadata:
4  name: ingress-nginx-controller
5  namespace: ingress-nginx
6data:
7  server-tokens: "false"

After updating the ConfigMap, the controller should reload its NGINX configuration. Depending on your setup, rollout timing may vary slightly.

Apply it with:

bash
kubectl apply -f ingress-nginx-config.yaml

Verify the Result

After applying the change, inspect the response headers.

bash
curl -I https://example.com

Before the change, you may see a detailed version string. After the change, you should normally see only nginx rather than nginx/1.x.x.

Always verify from a real ingress endpoint, not just by inspecting YAML, because configuration drift and controller reload issues do happen.

The Controller Version Still Matters

Do not mistake header hiding for actual patching. Removing the version string does not fix vulnerabilities. You still need to update the ingress controller regularly.

This setting is defense-in-depth only. It reduces easy information disclosure, but it does not replace maintenance, network policy, or proper patching.

Hiding the Entire Server Header Is Harder

Many teams really mean "remove the Server header entirely." That is a different problem. Depending on the ingress controller build and enabled modules, removing the header completely may require:

  • custom NGINX template changes
  • extra modules such as headers-more
  • a reverse proxy in front of ingress
  • application or CDN-layer header rewriting

So the practical question is often whether you need to hide the version or remove the whole header. Those are not the same task.

Per-Ingress vs Controller-Wide Thinking

Version hiding is normally a controller-wide concern because the header comes from the ingress controller itself. It is not usually something to solve one ingress resource at a time.

That is why the ConfigMap is the usual place for this configuration instead of per-Ingress annotations.

Example of Inspecting the ConfigMap

You can verify the live controller configuration directly:

bash
kubectl get configmap ingress-nginx-controller -n ingress-nginx -o yaml

If the key is missing or set incorrectly, the controller will keep its default behavior.

Hiding version strings is reasonable, but security posture should still center on:

  • controller updates
  • restricted admin access
  • TLS configuration
  • WAF or policy controls where appropriate
  • monitoring and alerting

Removing version disclosure is useful, but it is a minor hardening step rather than a core security control.

Common Pitfalls

  • Thinking server-tokens: "false" removes the entire Server header.
  • Changing the ConfigMap and not verifying the live response headers afterward.
  • Assuming header hiding makes patching less important.
  • Trying to solve a controller-wide header issue with per-service application settings.
  • Forgetting that different NGINX ingress variants may expose configuration differently.

Summary

  • To hide the NGINX version string in ingress-nginx, set server-tokens to false in the controller ConfigMap.
  • This usually changes Server: nginx/x.y.z into a simpler Server: nginx.
  • Hiding the version is not the same as removing the entire header.
  • Verify the result with a real HTTP response check after applying the change.
  • Treat this as hardening, not as a substitute for patching and controller maintenance.

Related reading
Course
Beginner
27 lessons
10 hours
System Design Fundamentals

Build a strong foundation in designing scalable, reliable distributed systems.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

System Design practice on Codemia

Work through 120+ system design problems with detailed solutions, from rate limiters to multi-region storage.

Practice system design

All Rights Reserved.