Response header
< Server: nginxServer Header: Fingerprinting and How to Hide It
The Server header names the software that answered. Use it to find which layer replied, and hide version numbers in nginx, Apache and Cloudflare, with limits.
- Direction
- Response
- Category
- Diagnostics
- Spec
- RFC 9110 §10.2.4
On this page
TL;DR:
Servertells the client which software answered, such asnginx/1.27.2. It is most useful to you for working out which layer in front of your app produced a response. Dropping the version number (server_tokens off,ServerTokens Prod) is cheap, but it is minor hardening, not a security control.
Format
HTTP/1.1 200 OK
Server: nginx/1.27.2
The value is one or more product tokens with optional comments, most specific first. RFC 9110 section 10.2.4 says a server SHOULD NOT generate a Server field containing needlessly detailed information, and notes that generous values can be used for fingerprinting. It is optional: origin servers MAY send it.
Using it for diagnosis
When a request fails, the Server header is one of the quickest ways to say which hop spoke last. Examples of what you will meet:
| Value | Layer |
|---|---|
cloudflare | Cloudflare edge. Pair with the CF-Ray header. |
AmazonS3 | S3 directly or behind CloudFront. |
awselb/2.0 | An AWS Application Load Balancer answering itself, typical on a 502 or 503 it generated. |
envoy | Envoy, as used by many service meshes and gateways. |
nginx | nginx as a web server, ingress controller, or reverse proxy. |
An error page with Server: nginx could be the ingress in front of your app, or the app container’s own nginx. Look at the response body, then at Via and any vendor header. Behind a CDN, compare curl against the public hostname with curl against the origin IP using --resolve.
Hiding the version
nginx
http {
server_tokens off;
}
The nginx documentation describes server_tokens as enabling or disabling “emitting the nginx version on error pages and in the Server response header field”. After off, the header is Server: nginx and error pages still show a bare nginx footer. The directive does not delete the header.
Options for going further:
- The third-party headers-more module:
more_clear_headers Server;ormore_set_headers 'Server: web';. - In the commercial nginx Plus,
server_tokensaccepts a string, and an empty string disables theServerfield entirely (available since 1.9.13). server_tokens build;does the opposite for debugging: it adds the build name to the version (since 1.11.10).
Apache
ServerTokens Prod
ServerSignature Off
Prod yields Server: Apache. The other ServerTokens levels are Major (Apache/2), Minor (Apache/2.4), Min (Apache/2.4.x), OS, and Full, which adds the operating system and compiled-in modules. ServerSignature Off removes the version footer from error pages. Prod is the floor for the core directive: it does not delete the header.
Cloudflare and other CDNs
Proxied responses carry Server: cloudflare. Cloudflare’s Response Header Transform Rules cannot modify the server header, or any cf- or x-cf- header. Your origin’s Server value is replaced in any case, so work at the origin only to stop it leaking when the origin is reached directly.
Node, Go and others
Frameworks usually do not set Server; they set X-Powered-By instead. A Go net/http server sends no Server header unless you add one. Check what your reverse proxy adds with curl -sI.
How much does it help
Hiding the version stops a header-only banner grab and silences scanners and audit checklists that flag it. Beyond that:
- Exploit scanners do not trust headers. They send the exploit or probe a version-specific file and see what happens.
- Software shows itself through default error pages, the order and spelling of other headers, supported TLS and HTTP/2 behaviour, and static paths.
- A CVE for the exact version you run is the real risk, and removing a string does not change it.
Keep the product name (nginx) if it helps your own debugging, drop the version, and spend the effort on patching and on limiting what is reachable. The Express documentation takes the same position about X-Powered-By: it may discourage a casual exploit, but it does not stop a determined attacker identifying the framework.
Verify
curl -sI https://example.com | grep -i '^server'
curl -s -o /dev/null -D - https://example.com/does-not-exist | head -5
The second command checks the error response too, since version strings often survive on 404 and 500 pages and on responses from a different virtual host.
Related
Frequently asked questions
What is the Server header?
It is a response header in which the origin server, or a proxy or CDN acting as one, names the software that produced the response, for example nginx/1.27.2, Apache, or cloudflare. It is defined in RFC 9110 section 10.2.4 and is informational only: nothing in HTTP depends on it.
How do I remove the Server header in nginx?
server_tokens off removes the version, so the header becomes Server: nginx, but the header itself stays. Removing it entirely needs the third-party headers-more module (more_clear_headers Server;) or nginx Plus and the commercial server_tokens with an empty string, which stops the Server field being emitted. A CDN or proxy in front can also override it.
Does hiding the Server header make my site more secure?
Marginally. It stops casual scanners and banner grabs reading a version number from one header, and it satisfies audit checklists that flag it. It does not remove a vulnerability, and attackers fingerprint software from error pages, default files, TLS behaviour and response timing anyway. Patch the software; treat hiding as a minor extra.
Can I change the Server header on Cloudflare?
Not with Transform Rules. Cloudflare documents the server header as one you cannot modify, along with cf- and x-cf- headers. Proxied responses show Server: cloudflare. Your origin Server value is replaced.
Why does my response have two Server headers or a different one than my app sets?
Each hop can add its own. A load balancer or CDN replaces or overrides what the origin sent, and some proxies pass the origin value through while adding Via. Compare curl against the origin directly and against the public hostname to see which layer produced which value.
Sources
Related
X-Powered-By Header: Remove It in Express, PHP, Next.js
X-Powered-By advertises your framework, such as Express or PHP. Remove it in Express, PHP, Next.js, ASP.NET and nginx, and why it is hygiene, not security.
Via Header
Learn how the Via header tracks the path of HTTP requests through proxies and gateways. Debug routing issues and understand your network infrastructure.
User-Agent Header
Learn how the User-Agent header identifies the client software, browser, or application making HTTP requests. Understand user agent strings and best practices.
HTTP 502 Bad Gateway: nginx, ALB and Cloudflare Fixes
Fix 502 Bad Gateway: decode nginx error-log lines, php-fpm sockets, ALB keep-alive mismatches and Cloudflare 502 vs 52x, with curl checks.