Skip to content
Control Plane Labs

HTTP Header Inspector: Read Response Headers

Inspect HTTP response headers to debug redirects, caching, HSTS, CSP, CORS, and content negotiation with a repeatable, operator-friendly workflow.

Control Plane Labs Staff

Published September 26, 2026

The HTTP header inspector is useful after a proxy change, certificate renewal, cache edit, or security-header rollout. It makes the wire response visible instead of asking you to infer behavior from configuration. The question is not “does this header exist?” but “what decision does this value cause?”

What should you inspect first?

Start with the status code, final URL, and redirect chain. HTTP fields are case-insensitive name/value pairs, and RFC 9110, Section 5 defines how fields are represented and combined. A Location on a 301, 302, 307, or 308 is a routing instruction, not proof that the destination is healthy.

Then scan the response:

Review Headers to look for Question to answer
Representation Content-Type, Content-Encoding, Content-Length Can the client interpret the bytes and their transfer encoding?
Freshness Cache-Control, Age, ETag, Last-Modified, Vary May a cache reuse this response, and how does it validate it?
Transport policy Strict-Transport-Security, Location Will a browser stay on HTTPS, and where does the next hop go?
Browser policy Content-Security-Policy, X-Content-Type-Options, Referrer-Policy Which browser behaviors are enforced or restricted?
Application boundary Set-Cookie, Access-Control-Allow-Origin, Access-Control-Expose-Headers Are state and cross-origin reads scoped as intended?
Provenance Date, Server, Via, tracing fields Which clock, proxy, or service handled this response?

Resource types can need different values.

How do cache headers explain stale content?

RFC 9111 defines a cache as a store of response messages and the logic that decides when an equivalent request can reuse one. Cache-Control: no-store bars storage, while private prevents a shared cache from storing the response unless a more specific rule permits it. max-age=60 gives a freshness lifetime.

Age is a clue that a cache has served or held the response. ETag and Last-Modified are validators: a client can send them back in a conditional request, and the server can answer 304 Not Modified when the representation has not changed. Vary is easy to miss. It tells a cache which request fields affect selection, such as Accept-Encoding or Accept-Language, so the cache does not reuse a representation for the wrong request variant.

Compare the response from two locations when a change looks stuck. Record status, Age, Cache-Control, validators, Vary, and the final URL at each edge. A different ETag can mean that the content changed; a growing Age with an unchanged validator can mean you are still reaching a cache. The curl command builder helps prepare a reproducible request, while curl --head --verbose URL shows a local diagnostic exchange.

Which security headers change browser behavior?

Strict-Transport-Security is not a generic “TLS enabled” badge. RFC 6797, Section 6.1 says a user agent processes the policy when it receives a valid header over secure transport. max-age is required, and includeSubDomains extends the policy to subdomains. An HSTS header received over plain HTTP is ignored. Check the HTTPS response and inspect every redirect hop; adding the header only to a late application response does not protect an earlier insecure hop.

Content Security Policy has two distinct response headers. The CSP Level 3 specification defines Content-Security-Policy as an enforcing policy and Content-Security-Policy-Report-Only as a monitoring policy. Report-only mode does not block the request, but it can produce violation reports. If a deployment contains two enforcing policies, the browser processes both, so a permissive rule in one policy does not cancel a restriction in another.

X-Content-Type-Options: nosniff and Referrer-Policy have narrower jobs: MIME type handling and referrer disclosure. Read the MDN HTTP header reference for context, then compare the value with the resource you are protecting. Do not mark a header “secure” merely because it is present.

Why does a browser show fewer headers than the inspector?

A server-side inspector and browser JavaScript do not receive the same view. The Fetch standard’s header model allows duplicate header names, compares names case-insensitively, and treats Set-Cookie specially instead of combining it like ordinary fields. It also defines a CORS-exposed header-name list: a cross-origin script can read only the fields that the response makes available, alongside the standard safelisted fields.

That is why an in-browser fetch() may see Content-Type but not a custom tracing field or ETag. Access-Control-Expose-Headers can expose selected names to an authorized origin; it does not make the resource public or disable the browser’s origin checks. The inspector’s result should therefore be treated as the anonymous HTTP response from its own execution point, not as a promise about what every browser script can read.

Duplicate fields also deserve care. RFC 9110 allows repeated lines to be combined only when the field definition permits list-style recombination. Fields that opt into structured syntax use RFC 8941; a failed parse is treated as absent. Set-Cookie is the familiar exception, so keep cookie values separate and show the redirect hop where each field appeared.

A five-minute header review

  1. Start with a harmless URL. Use a public endpoint you control or a static asset. Never paste credentials into a URL or probe private networks.
  2. Save the chain. Record each status and Location, then verify that the final URL uses the intended scheme, host, and path. Check the redirect status pages if the behavior is surprising.
  3. Classify the response. Note content type and encoding before judging cache or browser policy. A document, API response, image, and download have different requirements.
  4. Check cache evidence. Compare Cache-Control, Age, validators, and Vary. If two edges disagree, repeat from a second network before changing the origin.
  5. Check security policy. Verify HSTS on HTTPS, read CSP as a policy rather than a presence flag, and confirm that cookie and CORS scope match the application.
  6. Reproduce locally. Use the curl command builder or curl --head --verbose with a redacted, read-only request. Keep the captured headers with the deploy note for comparison.

The tool reads one request, so bot mitigation, geographic routing, content negotiation, and cache keys can produce a different response. Use the TLS certificate inspector for certificate details and the DNS lookup for name resolution.

Frequently asked questions

What is an HTTP header inspector?+
It fetches a URL and displays the response status, redirect chain, and headers. It helps verify caching, content type, browser policy, cookies, and proxy behavior as delivered to an anonymous client.
Why is a header present on one redirect but missing on the final response?+
Each redirect is a separate response. The server or proxy may attach a header to one hop but not another, so inspect every status and the final response independently.
Does Cache-Control: max-age guarantee that a response is cached?+
No. It supplies freshness guidance. Storage and reuse still depend on the cache, request method, response status, authorization, and other applicable requirements.
Does HSTS work when sent over HTTP?+
No. A conforming user agent ignores an HSTS header received over insecure transport. Check the HTTPS response and include a valid max-age value.
Why can browser JavaScript not read every response header?+
Cross-origin fetch exposes only safelisted fields and names authorized by CORS. A server-side inspection can see the HTTP response without making those fields readable to browser script.
Are repeated response headers always safe to join with commas?+
No. Combine list-style fields only when their definitions allow it; keep Set-Cookie values separate.

Tags: #http, #headers, #web-development, #security, #caching