DEV Community

Alex Chen
Alex Chen

Posted on

HTTP Headers Every Developer Should Know (2026)

HTTP Headers Every Developer Should Know (2026)

Headers are the hidden conversation between client and server. Understanding them makes you better at debugging, performance, and security.

Request Headers (Client → Server)

GET /api/users HTTP/1.1
Host: example.com
Accept: application/json
Authorization: Bearer eyJhbGci...
Content-Type: application/json
User-Agent: Mozilla/5.0
X-Request-ID: req_abc123
Enter fullscreen mode Exit fullscreen mode
// The headers you'll use most:

// Host — Which domain you're requesting (required in HTTP/1.1)
Host: api.example.com
// Used for virtual hosting (one IP, many domains)

// Accept — What response formats you want
Accept: application/json              // Want JSON
Accept: text/html                     // Want HTML
Accept: */*                          // Anything is fine
Accept: text/html,application/xhtml+xml;q=0.9,*/*;q=0.8 // With priorities

// Authorization — Credentials
Authorization: Bearer <token>          // OAuth2/JWT tokens
Authorization: Basic <base64>         // Username:password encoded
Authorization: ApiKey <key>           // Custom API key pattern

// Content-Type — What you're sending (for POST/PUT/PATCH)
Content-Type: application/json       // JSON payload
Content-Type: application/x-www-form-urlencoded  // Form data
Content-Type: multipart/form-data    // File uploads
Content-Type: text/plain             // Raw text

// User-Agent — Who's making the request
User-Agent: MyClient/1.0             // Identify your client
// Servers use this to: block bots, serve different content, analytics

// Custom headers (X- prefix convention)
X-Request-ID: uuid                  // Trace requests across services
X-Forwarded-For: 1.2.3.4          // Original client IP (set by proxy)
X-Real-IP: 1.2.3.4                // Original client IP (nginx convention)
X-Correlation-ID: abc123           // Link related requests together
Idempotency-Key: pay_12345          // Prevent duplicate payments
Enter fullscreen mode Exit fullscreen mode

Response Headers (Server → Client)

// Status line + headers:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Content-Length: 1234
Cache-Control: max-age=3600
Date: Sat, 31 May 2026 12:33:00 GMT
ETag: "abc123"
X-RateLimit-Remaining: 95
X-Request-ID: req_abc123

// Content-Type — What you're getting back
Content-Type: application/json; charset=utf-8
Content-Type: text/html; charset=utf-8
Content-Type: image/png
Content-Type: application/octet-stream   // Binary download
Content-Type: application/pdf
// ⚠️ Always set charset for text types!

// Content-Length — Size of body in bytes
Content-Length: 12345
// Important for: progress bars, connection keep-alive, detecting truncation

// Content-Encoding — Compression
Content-Encoding: gzip               // Body is gzip-compressed
Content-Encoding: br                 // Brotli compressed (better ratio!)
// Saves 60-80% bandwidth on text responses

// Cache-Control — How long to cache
Cache-Control: no-cache              // Revalidate every time
Cache-Control: no-store              // Don't cache at all (sensitive data!)
Cache-Control: private               // Only browser can cache (not CDNs)
Cache-Control: public                // Anyone can cache (CDNs included)
Cache-Control: max-age=3600           // Cache for 1 hour
Cache-Control: max-age=86400, immutable  // Cache forever (hashed assets)
Cache-Control: s-maxage=300, must-revalidate  // CDN caches 5min, then revalidate

// ETag & If-None-Match — Conditional requests
ETag: "v1-abc123"                    // Version identifier of resource
// Client sends: If-None-Match: "v1-abc123" on next request
// Server responds: 304 Not Modified if unchanged (saves bandwidth!)

// Location — Redirect target
Location: https://example.com/new-url
// Sent with: 301 (permanent), 302 (temporary), 303 (see other), 307/308

// Set-Cookie — Set cookies on client
Set-Cookie: session_id=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=86400
Set-Cookie: theme=dark; Path=/; Max-Age=31536000
// HttpOnly = JS can't read (prevents XSS token theft)
// Secure = Only sent over HTTPS
// SameSite = CSRF protection (Strict/Lax/None)

// CORS headers (cross-origin requests)
Access-Control-Allow-Origin: *        // Or specific origin
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400            // Cache preflight results
Access-Control-Allow-Credentials: true  // Allow cookies with cross-origin
Access-Control-Expose-Headers: X-Request-ID, X-RateLimit-Remaining

// Rate limiting headers (send these on EVERY response!)
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 73
X-RateLimit-Reset: 1717184000          // Unix timestamp when limit resets
Retry-After: 60                            // On 429 responses

// Security headers
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload  // HTTPS only!
X-Content-Type-Options: nosniff                    // Don't sniff MIME type
X-Frame-Options: DENY                             // Prevent clickjacking
X-XSS-Protection: 1; mode=block                   // Basic XSS filter
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline'
Referrer-Policy: strict-origin-when-cross-origin     // Control referrer header
Permissions-Policy: camera=(), microphone=()      # Block camera/mic access
Enter fullscreen mode Exit fullscreen mode

Debugging Headers

// When things go wrong, check these FIRST:

// 1. Is it a caching issue?
// Check response headers:
//   Cache-Control: max-age=86400 → Browser won't re-request for 24h!
// Fix: Ctrl+Shift+R (hard reload) or add cache-busting query param

// 2. Is it a CORS issue?
// Browser console shows: "Access-Control-Allow-Origin"
// Check: Does your API return Access-Control-Allow-Origin?
// Check: Is the request preflighted (OPTIONS before actual request)?
// Complex requests (custom headers, non-GET/POST) trigger preflight

// 3. Is it a redirect loop?
// Check: Location header pointing back to itself?
// Check: HTTP vs HTTPS mixed content?

// 4. Is the response actually what you expect?
// Check: Content-Type matches what you're parsing
// Common gotcha: API returns HTML error page when you expect JSON

// 5. Practical debugging with curl:
curl -v https://api.example.com/data
# Shows ALL headers (request and response)  invaluable!

curl -I https://api.example.com/data
# Shows response headers only (HEAD request equivalent)

curl -D - https://api.example.com/data > /dev/null
# Save headers to stdout, discard body

// 6. Browser DevTools Network tab:
// Right-click any request → Copy as cURL
// See exact headers being sent/received
// Filter by: XHR/Fetch (API calls), Doc (page loads), etc.
Enter fullscreen mode Exit fullscreen mode

Performance Headers

// These headers directly impact your app's perceived speed:

// Keep-Alive (connection reuse)
Connection: keep-alive
Keep-Alive: timeout=5, max=100
// Avoids TCP handshake overhead for repeated requests

// Accept-Encoding (compression negotiation)
Accept-Encoding: gzip, deflate, br
// Always include br (brotli) — 15-25% better than gzip
// Your server should compress responses automatically

// Accept-Language
Accept-Language: en-US,en;q=0.9
// Server uses this for i18n content negotiation

// Early Hints (103 status) — send headers before body is ready
HTTP/1.1 103 Early Hints
Link: </style.css>; rel=preload, </script.js>; rel=preload
// Browser starts loading resources while server generates HTML!

// Server-Timing (measure backend performance)
Server-Timing: db=45, render=23, total=68
// Visible in Chrome DevTools → Timing → Server Timing
// Format: metric=value or metric="desc";dur=value
Enter fullscreen mode Exit fullscreen mode

Header Security Checklist

Every API response should include:
□ Content-Type (correct, with charset for text)
□ X-Request-ID (for tracing/debugging)
□ X-RateLimit-* headers (if rate limited)
□ Strict-Transport-Security (HTTPS sites)
□ X-Content-Type-Options: nosniff
□ X-Frame-Options (or CSP frame-ancestors)
□ Cache-Control (appropriate for data sensitivity)
□ CORS headers (only for browser clients)

Never expose in headers:
❌ Server version details (Server: nginx/1.24.0 → use generic)
❌ Internal IPs or architecture info
❌ Stack traces or file paths in error responses
❌ API keys, tokens, passwords
❌ Session IDs in URLs (referrer leakage!)
Enter fullscreen mode Exit fullscreen mode

Which header has caused you the most debugging pain?

Follow @armorbreak for more practical developer guides.

Top comments (0)