Network

How to View HTTP Headers in Chrome

See request and response headers for any page or asset in Chrome, plus a reference for the headers that actually change how your site behaves.

9 min read

Open DevTools with F12, switch to the Network tab, then reload the page. Click the first entry in the list, which is the document itself, and the Headers panel opens with three sections: General (URL, method, status code), Response Headers, and Request Headers.

That's the whole answer for the common case. The rest of this is the parts that trip people up and the headers worth reading once you're there.

Things that stop people finding the headers

  • Nothing in the list. The Network panel only records while it's open. Open DevTools first, then reload.
  • The document request is missing. A filter is active. Click All, and clear the filter box.
  • You're looking at a redirect. If the status is 301 or 302, the headers you want are on the final request. Enable Preserve log to keep the whole chain visible across navigations.
  • Headers look cached. A response served from disk cache shows the headers from when it was stored. Tick Disable cache for a true network round trip.
  • A header your server sets isn't there. A CDN or proxy may be stripping it. Compare against curl -I from outside the browser.

Response headers worth reading

Caching

HeaderWhat to check
Cache-Controlmax-age, no-store, immutable, s-maxage. The single biggest lever on repeat-visit speed.
ETag / Last-ModifiedEnables 304 responses. Present but never producing a 304 usually means a mismatch upstream.
AgeHow long a CDN has held this response. A large Age on HTML is often a bug.
VaryWhich request headers change the response. Vary: * destroys cacheability.

The pattern most sites want: hashed static assets get max-age=31536000, immutable, HTML gets something short or no-cache with an ETag. If your JavaScript bundle has max-age=0, every visit re-downloads it.

Compression and protocol

Content-Encoding should say br or gzip for anything text-based. If it's absent on your HTML, CSS or JS, you're shipping several times more bytes than necessary and it's usually a one-line server config fix.

The protocol isn't a header, but it's next to them: right-click the Network panel column headers and enable Protocol to see h2 or h3 per request. A site still on http/1.1 pays a real cost on pages with many small assets.

Security

Content-Security-Policy, Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, Referrer-Policy and Permissions-Policy. Each of these is covered properly in the website security checks guide; for now, note that the Network panel is where you confirm they're actually being sent, as opposed to configured somewhere and silently dropped.

Content type

Content-Type decides how the browser interprets the bytes. A JSON API returning text/html will still parse if you call .json() on it, but Content-Type: text/plain on a .js file plus X-Content-Type-Options: nosniff means the script won't execute at all. The charset matters too: text/html without charset=utf-8 produces mojibake on any page that doesn't declare it in a meta tag.

CORS

When a cross-origin request fails, the browser's console message is deliberately vague. The headers tell you more:

http
Access-Control-Allow-Origin: https://app.example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization

Two rules catch most CORS bugs. Access-Control-Allow-Origin: * cannot be combined with credentials, so a wildcard plus withCredentials: true fails. And a preflight is a separate OPTIONS request with its own headers, so check that one rather than the GET you were expecting.

Request headers worth reading

  • `Cookie` — everything the browser is sending. Large cookie payloads go out with every single request to the domain, including images.
  • `Authorization` — check the scheme and that the token is the one you think it is. WDT's JWT Inspector decodes bearer tokens if you need to read the claims.
  • `Accept-Encoding` — if it doesn't include br, you won't get Brotli back no matter what the server supports.
  • `Referer` — governed by your Referrer-Policy. Useful for confirming that policy is doing what you expect.
  • `User-Agent` — worth checking when a server behaves differently for you than for a crawler.

Checking headers without the Network panel

The Network panel is thorough, and thorough is sometimes more than you need. If the question is just "is compression on, is caching sane, is HSTS set," opening DevTools, reloading, finding the document request and scrolling to the right section is more ceremony than the question deserves.

Around 34 network utilities in Web Developer Tools answer these one question at a time. View HTTP Response Headers opens the document's headers in a searchable report, Copy Response Headers puts them on the clipboard, and there are focused checks that read one thing and tell you the answer: Detect Compression, Detect Cache Headers, Detect HTTP Version, Detect ETag, Detect CORS Headers, Detect Redirects, Detect CDN.

Alongside those sit the whole-page views: List All Network Resources for a table of everything loaded, Resource Type Breakdown for where the weight is, Find Slow Resources and Find Failed Resources for the requests that need attention, and HAR Export when you need to hand the whole session to someone else.

Reading headers for assets, not just the page

The document's headers are the ones people check. The interesting problems are usually on the assets:

  1. 1Sort the Network panel by Size and look at the largest few responses
  2. 2Check each one's Cache-Control and Content-Encoding
  3. 3Look for anything served from your origin that should be on a CDN
  4. 4Check Vary on anything served through a cache
  5. 5Look at the Time column and open the timing breakdown for anything slow — a long Waiting (TTFB) is a server problem, a long Content Download is a size problem

That five-step pass takes a couple of minutes and regularly finds a font with no cache headers or an uncompressed 400KB JSON blob.

One more thing about status codes

The General section shows the status. A few that mean more than they appear to:

  • 200 (from disk cache) — didn't hit the network at all
  • 204 — succeeded with no body, normal for beacons and analytics
  • 206 — partial content, expected for video and range requests
  • 304 — your validation headers are working
  • 308 vs 301 — 308 preserves the request method, which matters for POST endpoints
  • 499 / 0 / (failed) — the request was cancelled, often by a navigation or an aborted fetch, not by the server

Headers are the connective tissue between a lot of other work: they decide how fast repeat visits are, they carry your security posture, and they're on the pre-launch checklist for good reason.

Related reading

All 15 articles