DevToolsForYou
Utilities

How to Read HTTP Headers

A practical guide to HTTP headers — request vs response headers, what the most important ones mean, how to inspect them in the browser and curl, and security headers you should be setting.

2 min readUpdated Apr 11, 2026

What HTTP headers are

Headers are key-value metadata pairs sent before the body of every HTTP request and response. They describe the content type, caching rules, authentication credentials, encoding, and dozens of other properties. Header names are case-insensitive. They cannot contain newlines — a header value must be on one line.

Inspecting headers in the browser

Open DevTools (F12), go to the Network tab, reload the page, click on any request. The Headers tab shows all request and response headers split into sections. The most useful section is Response Headers — look for Content-Type, Cache-Control, and any X- or security headers. The Timing tab shows how caching is affecting load time.

Inspecting headers with curl

bash
# Show only response headers (HEAD request)
curl -I https://example.com

# Show headers and body
curl -i https://example.com

# Show verbose — request headers, TLS info, and response
curl -v https://example.com

# Send a custom request header
curl -H 'Authorization: Bearer token123' https://api.example.com/me

# Send JSON body with correct Content-Type
curl -X POST https://api.example.com/data \
  -H 'Content-Type: application/json' \
  -d '{"key": "value"}'

The most important request headers

text
Authorization: Bearer eyJhbGci...   # API authentication
Content-Type: application/json     # body format you are sending
Accept: application/json           # format you want back
Cookie: session=abc123             # stored cookies
Origin: https://yourapp.com        # sent by browser on cross-origin requests
If-None-Match: "abc123"            # conditional — return 304 if ETag matches

The most important response headers

text
Content-Type: application/json; charset=utf-8  # what the body is
Cache-Control: max-age=3600, public             # how long to cache
ETag: "33a64df5"                                # version token for caching
Set-Cookie: session=abc; HttpOnly; Secure       # set a cookie
Location: /new-path                             # redirect destination
Access-Control-Allow-Origin: *                  # CORS — allow cross-origin reads

Security headers you should set on every response

These headers are not set by default and must be added explicitly. They harden your site against XSS, clickjacking, MIME sniffing, and downgrade attacks.

text
# Force HTTPS for 1 year, including subdomains
Strict-Transport-Security: max-age=31536000; includeSubDomains

# Restrict scripts to same origin — prevents most XSS
Content-Security-Policy: default-src 'self'

# Prevent MIME type sniffing
X-Content-Type-Options: nosniff

# Prevent embedding in iframes (clickjacking)
X-Frame-Options: DENY

# Control referrer information leakage
Referrer-Policy: strict-origin-when-cross-origin

# Check your headers: securityheaders.com

Reading Cache-Control

Cache-Control is the most complex response header. Understanding it explains why users see stale content after deployments.

text
# Do not cache at all (for authenticated or dynamic content)
Cache-Control: no-store

# Cache locally but revalidate with server before using
Cache-Control: no-cache

# Cache for 1 hour in browsers and CDNs
Cache-Control: public, max-age=3600

# Cache in browser only (not CDN) for 1 day
Cache-Control: private, max-age=86400

# Content-addressed assets (e.g. main.abc123.js) — cache forever
Cache-Control: public, max-age=31536000, immutable
Frequently asked questions

What does a 304 Not Modified response mean?

It means the resource has not changed since the client last fetched it. The server returns no body — just the 304 status. The client uses its cached copy. This is triggered by conditional request headers: If-None-Match (matched an ETag) or If-Modified-Since (resource has not changed since that date).

Why do I get a CORS error even though my server is running?

The browser is blocking the response because the server did not include the Access-Control-Allow-Origin header matching your frontend's origin. CORS errors are enforced by the browser, not the server — curl will succeed even when the browser blocks it. Add the appropriate CORS headers to your server responses.

Related cheatsheetsAll cheatsheets →
Related guidesAll guides →