IT
OmnvertImage • Document • Network
Jul 06, 2026intermediate9 minhttp · headers · caching · cdn · security-headersHTTP Header InspectorMore guides for this tool

Reading HTTP Response Headers to Debug Caching and Security

The response headers tell you whether a CDN cached your page, how long a browser will hold it, and which security policies are in force. Here is how to read the ones that matter.

Step-by-step

  1. Fetch the headers for a URL

    Paste the full URL into the HTTP Header Inspector and it issues a request and shows you the raw response headers the server sent back. Test the exact URL a user hits, including the path and any query string, because caching and redirects can differ per path. If you are chasing a caching problem, request the same URL twice and compare; the interesting fields often only settle into their real values on the second hit once a CDN has populated its cache.

  2. Start with the status line

    The first line is the status code, and it frames everything below it. A 200 is a normal hit. A 301 or 302 means you are being redirected, and the Location header tells you where; follow that chain because a header you expected may live on the final URL, not the one you typed. A 304 Not Modified is a caching success, the server confirming the client's cached copy is still fresh. A 5xx means the origin failed, and any cache headers on it describe how long that error itself might be cached, which can be a nasty surprise.

  3. Read Cache-Control, ETag, and Age together

    Cache-Control is the primary caching instruction. max-age=3600 means fresh for an hour; no-store means never cache; private means browsers may cache but shared CDNs must not; s-maxage overrides max-age for CDNs specifically. ETag is a content fingerprint the client sends back in If-None-Match to ask if anything changed, enabling those efficient 304 replies. Age tells you how many seconds an object has already sat in a cache, so a large and growing Age proves the CDN is serving a stored copy rather than fetching from origin each time.

  4. Find the CDN HIT or MISS marker

    Most CDNs stamp their cache decision into a header, though the name varies: x-cache: HIT, cf-cache-status: HIT, x-served-by, or age combined with a via header. HIT means the edge served the object from cache without touching your origin; MISS means it went back to origin for this request, usually because the cache was cold or the object had expired. If you expected caching but every request reports MISS, look upward at Cache-Control on the origin response; a no-store or a missing max-age tells the CDN not to keep anything.

  5. Check Content-Type and Content-Encoding

    Content-Type declares what the body actually is, including the charset, like text/html; charset=utf-8 or application/json. A wrong type causes real bugs: a JSON API mislabeled as text/plain can break a client parser, and a mojibake page is almost always a charset mismatch here. Content-Encoding shows compression, usually gzip or br for Brotli. If a large text asset comes back with no Content-Encoding, compression is not happening and you are shipping far more bytes than you need to, which is an easy performance win to catch from the headers alone.

  6. Audit the security headers

    A few headers harden the response. Strict-Transport-Security tells browsers to only use HTTPS for a set max-age, which shuts down downgrade attacks; check the seconds value and whether includeSubDomains is present. Content-Security-Policy restricts where scripts, styles, and frames may load from, and it is the strongest defense against injected script. X-Content-Type-Options: nosniff stops the browser from guessing a MIME type and mis-executing a file. Their absence is not an error the server reports; you only notice it by reading the headers and finding the line missing.

  7. Note the Server and redirect Location

    The Server header names the software answering, like nginx or cloudflare, and it is a quick way to confirm which layer responded, an edge node or your origin. On a redirect, the Location header carries the target URL; a common gotcha is a redirect loop where Location points back at a URL that redirects again. Because these are transport-level details, pair the header read with a TLS / SSL Checker when a redirect is jumping between HTTP and HTTPS, so you can see the certificate on the final endpoint too.

A sample header dump

Here is a trimmed response from a page served through a CDN. Read it top to bottom: a 200 status, a cache HIT with a non-zero Age proving the edge is serving stored bytes, Brotli compression, and the core security headers all present.

http
HTTP/2 200
content-type: text/html; charset=utf-8
content-encoding: br
cache-control: public, max-age=3600, s-maxage=86400
age: 512
etag: "a1b2c3d4e5"
cf-cache-status: HIT
strict-transport-security: max-age=63072000; includeSubDomains; preload
content-security-policy: default-src 'self'; script-src 'self'
x-content-type-options: nosniff
server: cloudflare

Fast checks for a caching problem

  1. Is Cache-Control on the origin permissive? A no-store or private stops any shared cache cold.
  2. Does the cache-status header say HIT on the second request? A permanent MISS means the CDN is refusing to store the object.
  3. Is Age climbing across requests? A growing Age confirms the edge is holding the copy rather than re-fetching.
  4. Is a Set-Cookie present? Many CDNs refuse to cache responses that set cookies, which quietly disables caching.
Headers are case-insensitive; values are not

Cache-Control and cache-control are the same header, and HTTP/2 lowercases every field name on the wire, so do not read meaning into the casing. The values are a different story: a directive like no-cache is not the same as no-store, and a token typo in a Content-Security-Policy silently drops that rule. Read values exactly.

Related