Every Common Response Header and What It Is For
A response is a status line, a set of headers and a body. The body is what you see; the headers decide how the browser treats it. This page goes through the headers the checker reports, family by family, with the value worth sending.
Content Headers: What the Body Is
Content-Type is the one header no response should lack. text/html; charset=utf-8 tells the browser to parse HTML and decode it as UTF-8; application/json, image/webp and text/css do the same for their formats. When it is missing or wrong, browsers guess from the bytes, which is slow and occasionally dangerous, and X-Content-Type-Options: nosniff exists to forbid the guessing. For HTML the charset part matters: without it, and without a meta charset in the first kilobyte, accented characters render as question marks in some browsers.
Content-Encoding names the compression applied to the body: gzip, br (Brotli, better) or zstd. It only appears when the request said it could accept compression, which is why the checker sends Accept-Encoding by default and lets you switch it off to compare. Content-Length is the body size in bytes and is absent on chunked responses. Content-Disposition: attachment turns a page view into a download. Link carries relations (preload, canonical, hreflang alternates) that would otherwise need HTML tags, which makes it the way to attach them to a PDF.
Caching Headers: How Long to Keep It
Cache-Control is a comma-separated list of directives. max-age=31536000, immutable says "keep for a year and never revalidate", right for files whose name changes when the content does. no-cache says "keep it, but ask me before using it", which is what most HTML pages want. no-store says "never write it to disk", for pages with personal data. private keeps shared caches (CDNs, proxies) out; public lets them in. s-maxage gives CDNs their own lifetime. stale-while-revalidate lets a cache serve the old copy while it fetches a new one in the background.
ETag and Last-Modified are validators: the browser sends them back as If-None-Match and If-Modified-Since, and the server answers 304 Not Modified with no body when nothing changed. A response with a short max-age and no validator has to be fully downloaded on every expiry. Expires is the HTTP/1.0 way to say max-age and loses when both are present. Vary lists the request headers that change the response; Vary: Accept-Encoding belongs on every compressed response, and Vary: User-Agent or Vary: * mostly makes the response uncacheable. Age is how long a shared cache has held the copy; anything above zero means the origin was not asked.
# static assets with hashed filenames Cache-Control: public, max-age=31536000, immutable # HTML pages Cache-Control: no-cache ETag: "5f3a2c-1a4" # personal pages Cache-Control: private, no-store
Status and Redirect Headers
Location is where a 3xx sends the client and where a 201 says the new resource lives. It should be an absolute URL, it should not point at another redirect, and it should not point from https to http. Retry-After accompanies 503 and 429 and tells clients, including Googlebot, how long to wait. Allow lists methods with a 405. Refresh is a non-standard header (also written as a meta tag) that reloads or redirects after N seconds; search engines treat it as a weaker signal than a real 301, and visitors see a blank pause. The status code reference covers which code to send with each.
Security Headers: What the Page May Do
Six headers cover most of it. Strict-Transport-Security pins the host to HTTPS for max-age seconds. Content-Security-Policy whitelists where scripts, styles, images and frames may load from and is the only real defence once a script is injected. X-Content-Type-Options: nosniff stops type guessing. X-Frame-Options (or the CSP frame-ancestors directive that replaces it) prevents clickjacking. Referrer-Policy limits what the Referer header leaks when visitors follow links. Permissions-Policy switches off browser features the page does not use. The checker reports which are present; grading their values is a job for our sister site securityheaders.tools.
Strict-Transport-Security: max-age=31536000; includeSubDomains Content-Security-Policy: default-src 'self' X-Content-Type-Options: nosniff X-Frame-Options: SAMEORIGIN Referrer-Policy: strict-origin-when-cross-origin Permissions-Policy: camera=(), microphone=(), geolocation=()
Cross-Origin Headers
Browsers refuse to let a script on one origin read a response from another unless the response says it may. Access-Control-Allow-Origin names the origin allowed (or * for anyone, which is fine for public data and forbidden together with credentials). Access-Control-Allow-Methods and -Headers answer the preflight OPTIONS request for anything beyond a simple GET. Access-Control-Allow-Credentials lets cookies ride along. Timing-Allow-Origin is the same idea for performance timings. None of these affect a page you load directly, only scripts fetching it from elsewhere.
Server and Platform Headers
Server and X-Powered-By describe the software. Neither does anything useful for a visitor, and both often include versions (nginx/1.18.0, PHP/7.4.3) that tell an attacker where to start. Remove X-Powered-By entirely and trim Server to the product name. Via lists proxies on the path. Alt-Svc advertises HTTP/3. CDN headers such as CF-Cache-Status, X-Cache and X-Served-By say whether the edge served from cache and are the first thing to read when a page is slow: a MISS means the origin did the work.
Headers That Should Not Be There
X-XSS-Protection enabled the old browser XSS filter, which was removed after it turned out to create vulnerabilities of its own; send 0 or nothing. P3P was a 2002 privacy format only Internet Explorer read. X-UA-Compatible picked an Internet Explorer rendering engine. Expect-CT was retired when Certificate Transparency became mandatory. Pragma: no-cache is an HTTP/1.0 relic that Cache-Control replaced. None of them break anything; they are just weight and a sign the configuration has not been looked at in a while.
Questions People Ask About Response Headers
What is an HTTP response header?
A response header is a name and value the server sends before the body of a page or file. Headers tell the browser what the body is, how long to keep it, whether it may be framed, where a redirect goes, and dozens of other things the body itself cannot say.
What is the difference between Cache-Control max-age and Expires?
Both say how long a response may be reused. max-age is a number of seconds from when the response was received; Expires is an absolute date. When both are present every current browser and cache uses max-age and ignores Expires.
What does Vary: Accept-Encoding do?
It tells caches that the response differs depending on the Accept-Encoding request header, so a compressed copy must only be served to clients that accept that compression. Without it a shared cache can hand gzip bytes to a client that cannot decode them.
How do I check the headers a page sends?
Paste the URL into the checker on the home page, or in a browser open the developer tools, go to the Network tab, reload, and click the first request. Command-line users run curl -I followed by the URL for a HEAD request, or curl -sD - -o /dev/null for the headers of a GET.
Why do I see different headers than the checker?
Because the server may vary its answer by user agent, by cookies, by the region it thinks you are in, or by whether a CDN served the copy. The checker fetches as an anonymous visitor from its own server; choose a different user agent on the home page to compare.
Is the Server header a security risk?
The product name alone is not. A version number is a small risk: it tells an attacker which known vulnerabilities to try. Most servers can be configured to send only the name, and a CDN in front usually replaces it anyway.