> ## Documentation Index
> Fetch the complete documentation index at: https://notes.kodekloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# HTTP Headers

> Overview of HTTP headers, their types, security, caching, CORS, proxy usage, and NGINX configuration best practices.

HTTP headers are the metadata for web requests and responses — like the details you write on an envelope (sender, recipient, date, priority). They’re simple key-value pairs separated by a colon and tell servers and clients how to process a message: what format is expected, how responses should be cached, what security policies apply, and more.

Quick example — basic request headers:

```http theme={null}
GET / HTTP/2
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT) Firefox/103.0
Accept: text/html
Accept-Language: en-US
Connection: keep-alive
Pragma: no-cache
Cache-Control: no-cache
```

Host is the key and `example.com` is the value.

Types of headers and where they fit

* General headers: apply to both requests and responses (metadata about the message).
* Request headers: sent by the client to describe the request and the client’s capabilities.
* Response headers: sent by the server to describe the response and the server.
* Security, Authentication, Caching, CORS, Proxy, and Custom headers: specialized categories for specific concerns.

![A presentation slide titled "Types of HTTP Headers" with two colored boxes labeled "General Headers" and "Request/Response Headers." The request/response box lists examples: Security, Authentication, Caching, CORS, Proxy, and Custom headers.](https://mintcdn.com/kodekloud-c4ac6d9a/x1wBthvq78ZWHRHX/images/Nginx-for-Beginners/Security/HTTP-Headers/http-headers-general-request-response.jpg?fit=max\&auto=format\&n=x1wBthvq78ZWHRHX\&q=85\&s=ae2ff4ca48ed523d49248be244243176)

General headers

* Used in both requests and responses to convey message metadata (server name, connection directives, status, etc.).

Request headers

* Sent by the client to tell the server about the request and client capabilities.
* Common headers: `Accept`, `Accept-Encoding`, `Accept-Language`, `User-Agent`, `Cookie`.
* HTTP/2 uses pseudo-headers (prefixed with `:`) such as `:method`, `:path`, `:scheme`, and `:authority`.

Example request (HTTP/2 pseudo-headers plus common headers):

```http theme={null}
:authority: kodekloud.com
:method: GET
:path: /
:scheme: https
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,es;q=0.8
Cache-Control: max-age=0
Cookie: cookiesModal=Set; cf_clearance=...
Priority: u=0, i
Referer: https://www.google.com/
Sec-CH-UA: "Google Chrome";v="131", "Chromium";v="131", "Not_A Brand";v="24"
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: "macOS"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: cross-site
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36
```

* `User-Agent`: identifies browser and platform; useful for analytics and troubleshooting.
* `Accept-Language`: informs the server of preferred languages for content negotiation.

Response headers

* Sent by the server to describe the response and server characteristics.
* Common examples: `Content-Type`, `Date`, cache headers, and security headers.

Example response headers (Cloudflare + cache metadata):

```http theme={null}
Age: 387887
Cf-Cache-Status: DYNAMIC
Cf-Ray: 90387f9e5f24aabd-YYZ
Content-Encoding: br
Content-Security-Policy: frame-ancestors 'self' https://*.webflow.com http://*.webflow.com http://*.webflow.io http://webflow.com https://webflow.com
Content-Type: text/html
Date: Fri, 17 Jan 2025 18:44:46 GMT
Nel: {"success_fraction":0,"report_to":"cf-nel","max_age":604800}
Report-To: {"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=..."}],"group":"cf-nel","max_age":604800}
Server: cloudflare
Server-Timing: cfL4;desc="? proto=TCP&rtt=49884&min_rtt=49368&rtt_var=8332&sent=7&recv=11&lost=0&retrans=0&sent_bytes=1918&recv_bytes=3057&delivery_rate=54552&cwnd=253&unsent_bytes=0&cid=ccaf72a1437ce785&ts=109&x=0"
Vary: Accept-Encoding,x-wf-forwarded-proto
X-Cache: HIT, HIT
X-Cache-Hits: 57,1
X-Lambda-Id: ee303bec-767f-4c38-b236-246921948478
X-Served-By: cache-iad-kcgs7200070-IAD, cache-yyz4562-YYZ
X-Timer: S1737139486.494748,VS0,VE1
```

Caching headers (overview)

* Improve performance and reduce origin load by controlling how clients and intermediaries cache content.
* Key headers: `Cache-Control`, `Expires`, `ETag`, `Age`, `Vary`.

Example showing caching metadata (response + request):

```http theme={null}
Response Headers:
Accept-Ranges: bytes
Access-Control-Allow-Origin: *
Cache-Control: max-age=0, must-revalidate
Content-Encoding: gzip
Content-Length: 44549
Content-Security-Policy: frame-ancestors 'self' *.espn.com ...
Content-Type: text/html;charset=UTF-8
Date: Sat, 18 Jan 2025 18:31:33 GMT
Etag: W/"e971e162bb5ef8926a2284952c25053292be8cdd"
Set-Cookie: edition-view=espn-en-us; path=/; Expires=Sat, 25 Jan 2025 18:31:33 GMT;
Vary: Accept-Encoding
Via: 1.1 varnish (Varnish/6.0), 1.1 e0f558b3f7fa7ada5748649f809b0b0.cloudfront.net (CloudFront)
X-Amz-Cf-Id: BfvqigAzW_f9PrqDEU-...
X-Amz-Cf-Pop: ORD58-P10
X-Cache: Miss from cloudfront

Request Headers:
:authority: www.espn.com
:method: GET
:path: /
:scheme: https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: en-US,en;q=0.9,es;q=0.8
Cache-Control: max-age=0
Cookie: country=ca; SWID=...
```

* `ETag`: unique identifier for a resource version; used with `If-None-Match` for conditional requests (304 Not Modified).
* `X-Cache`: indicates CDN/proxy cache status (`HIT`, `MISS`, `BYPASS`).

Security headers

* Protect applications from XSS, clickjacking, protocol downgrades, and other threats.
* Common security headers: `Content-Security-Policy`, `X-Content-Type-Options`, `X-Frame-Options` or `frame-ancestors`, `Strict-Transport-Security`, `Referrer-Policy`, `Permissions-Policy`.

Example response headers (Gmail-like CSP + security headers):

```http theme={null}
alt-svc: clear
cache-control: no-cache, no-store, max-age=0, must-revalidate
content-encoding: gzip
content-security-policy: script-src 'nonce-6tCIRsH6znR2cX-hVemx5A' 'unsafe-inline' 'strict-dynamic' https: http: 'unsafe-eval'; object-src 'none'; base-uri 'self'; report-uri https://mail.google.com/mail/cspreport; require-trusted-types-for 'script'
content-type: text/html; charset=utf-8
cross-origin-resource-policy: same-site
date: Sat, 18 Jan 2025 17:03:06 GMT
expires: Mon, 01 Jan 1990 00:00:00 GMT
permissions-policy: ch-ua-arch=*, ch-ua-bitness=*, ch-ua-full-version=*, ch-ua-full-version-list=*, ch-ua-model=*, ch-ua-wow64=*, ch-ua-form-factors=*, ch-ua-platform=*, ch-ua-platform-version=*
pragma: no-cache
reporting-endpoints: default="/mail/u/0/web-reports?cached=true&hub-config=1&dtid=5608829486345944565&b1=gmail.pinto-server_20250115_09_p0"
server: ESF
strict-transport-security: max-age=10886400; includeSubDomains
vary: Sec-Fetch-Dest, Sec-Fetch-Mode, Sec-Fetch-Site
x-content-type-options: nosniff
x-dns-prefetch-control: off
x-frame-options: SAMEORIGIN
x-xss-protection: 0
```

Table — common security headers and purpose

| Header | Purpose |
| - | - |
| `Content-Security-Policy` | Restrict allowed sources for scripts, styles, frames, etc. Reduces XSS risk. |
| `X-Content-Type-Options: nosniff` | Stops MIME-sniffing; enforces declared `Content-Type`. |
| `X-Frame-Options` / `frame-ancestors` | Prevents clickjacking by restricting embedding in frames. |
| `Strict-Transport-Security` | Enforces HTTPS (HSTS) for future requests. |
| `Referrer-Policy` | Controls the amount of referrer information sent. |
| `Permissions-Policy` | Enable/disable browser features (e.g., camera, geolocation). |

Authentication headers

* Used to authenticate clients to servers.
* Examples: `Authorization: Basic <base64>`, `Authorization: Bearer <token>`.

Example request with Basic auth:

```http theme={null}
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.8,hi;q=0.6,es;q=0.4,it;q=0.2
Authorization: Basic YWRtaW46YWRtaW4xMjM=
Connection: keep-alive
Cookie: SESSc2feff1f8f7f835b8e96b2c60e208dfa=...
Host: localhost:8080
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36
```

* Note: Basic auth is simply base64 of `user:password` — do not send credentials over plain HTTP. Use `Authorization: Bearer <token>` for token-based flows (OAuth, JWTs).

CORS (Cross-Origin Resource Sharing)

* CORS headers let servers control which external origins can access resources and what HTTP methods/headers are allowed in cross-origin requests.

![A slide titled "CORS Header" showing a simple diagram of a webpage, a globe/network and servers with arrows labeled "Retrieves data" and "Includes CORS headers." It illustrates that CORS controls resource requests between different domains to protect data.](https://mintcdn.com/kodekloud-c4ac6d9a/x1wBthvq78ZWHRHX/images/Nginx-for-Beginners/Security/HTTP-Headers/cors-header-cross-domain-requests-diagram.jpg?fit=max\&auto=format\&n=x1wBthvq78ZWHRHX\&q=85\&s=2590a7883ce3cc7811c69058d38feb20)

Example OPTIONS preflight response:

```http theme={null}
Request URL: https://petexchangehk.herokuapp.com/auth/login/success
Request Method: OPTIONS
Status Code: 204 No Content

Response Headers:
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: access-control-allow-credentials,content-type
Access-Control-Allow-Methods: GET, POST, PUT, DELETE
Access-Control-Allow-Origin: https://petexchangehk-frontend.vercel.app
Connection: keep-alive
Content-Length: 0
Date: Mon, 19 Sep 2022 13:23:51 GMT
Server: Cowboy
Vary: Origin, Access-Control-Request-Headers
Via: 1.1 vegur
X-Powered-By: Express
```

Table — key CORS headers

| Header | Purpose |
| - | - |
| `Access-Control-Allow-Origin` | Which origins are permitted to access the resource. |
| `Access-Control-Allow-Methods` | Allowed HTTP methods for cross-origin requests. |
| `Access-Control-Allow-Headers` | Which request headers can be used during the actual request. |
| `Access-Control-Allow-Credentials` | Whether cookies and credentials are allowed. |

Note: CORS is an application-level decision and often requires coordinating backend and frontend domains for safe configuration.

Proxy headers

* When requests traverse proxies, CDNs, or load balancers, these headers preserve original client information:
  * `X-Forwarded-For`: originating client IP + proxy chain (comma-separated).
  * `X-Forwarded-Host`: original Host header.
  * `X-Forwarded-Proto`: original protocol (`http` or `https`).
  * `X-Forwarded-Server`: hostname of the proxy that forwarded the request.
  * `X-Real-IP`: single client IP when there’s only one proxy.

Example environment-like listing showing typical forwarded headers:

```text theme={null}
HOST                        'web:8001'
UPGRADE_INSECURE_REQUESTS   '1'
USER_AGENT                  'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36'
X_FORWARDED_FOR             '192.168.122.4'
X_FORWARDED_HOST            'web.domain.com'
X_FORWARDED_PROTO           'https'
X_FORWARDED_SERVER          '172.19.0.5'
```

* Useful for logging, rate-limiting, geo-based decisions, and for upstream services that need the original client context.

Custom headers

* Applications and intermediaries often add non-standard headers for tracing, metadata, or feature flags: `X-Custom-Header`, `X-Request-ID`, etc.

Example request with a custom header:

```http theme={null}
GET /api HTTP/1.1
Host: example.com
User-Agent: curl/8.1.2
Accept: */*
X-Custom-Header1: Value1
```

NGINX built-in variables

* NGINX exposes built-in variables (prefixed with `$`) for dynamic behavior in configurations.

Common NGINX variables:

1. `$remote_addr` — client IP address
2. `$remote_port` — client source port
3. `$server_addr` — NGINX server IP address
4. `$request` — full request line (e.g., `GET /index.html HTTP/1.1`)
5. `$uri` — current URI path without args (e.g., `/index.html`)
6. `$request_uri` — full request including args (e.g., `/index.html?user=Anthony`)
7. `$request_method` — request method (e.g., `GET`, `POST`)
8. `$args` — query string (e.g., `id=1234&name=example`)
9. `$http_<header_name>` — incoming HTTP header (e.g., `$http_user_agent`)
10. `$http_referer` — `Referer` header value
11. `$status` — response status code (e.g., `200`, `404`)
12. `$upstream_addr` — address of the upstream that handled the request
13. `$scheme` — `http` or `https`
14. `$host` — original Host header (domain)
15. `$ssl_protocol` — TLS protocol used (e.g., `TLSv1.2`)
16. `$ssl_cipher` — TLS cipher used
17. `$http_cookie` — raw Cookie header from the client

You can combine variables to construct the original request URL:

```text theme={null}
Source link: $scheme://$host$request_uri
```

Use cases: logging, conditional routing, header transformation, and forwarding client details to upstreams.

NGINX example: sending headers and proxying

* `add_header` sets headers on responses sent from NGINX to the client.
* `proxy_set_header` sets or overrides headers on requests forwarded to upstream backends.

Example `server` block showing common headers and proxy directives:

```nginx theme={null}
server {
    listen       443 ssl;
    server_name  honda.cars.com;

    ssl_certificate /etc/ssl/certs/honda.cars.com.crt;
    ssl_certificate_key /etc/ssl/private/honda.cars.com.key;

    root   /var/www/honda.cars.com/html;
    index  index.html;

    # Strict-Transport-Security must be sent over HTTPS; include this in your TLS server block
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Frame-Options "SAMEORIGIN";
    add_header Content-Security-Policy "default-src 'self'";
    add_header Referrer-Policy "origin";

    location / {
        # Headers set on requests forwarded to the upstream backend
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_pass http://backend_upstream;
    }
}
```

* In this configuration, requests for `honda.cars.com` are proxied to `backend_upstream`. `proxy_set_header` forwards client details to the upstream, and `add_header` supplies security/caching headers back to the browser.
* Remember: HSTS (`Strict-Transport-Security`) is only meaningful when sent over HTTPS.

Final notes and best practices

* HTTP headers are central to content negotiation, caching, security, authentication, and the flow of information across clients, proxies, and servers.
* Never expose sensitive information in response headers (e.g., internal tokens, credentials).
* Use secure defaults: enable CSP, set `X-Content-Type-Options: nosniff`, and prefer `Strict-Transport-Security` for HTTPS sites.
* Use `ETag`/conditional requests and appropriate `Cache-Control` settings to optimize performance.
* When behind proxies, rely on forwarded headers (`X-Forwarded-*`, `X-Real-IP`) to preserve original client context for logging and upstream logic.
* Test header behavior locally and in staging: inspect requests and responses with browser dev tools, `curl -v`, or a local proxy (e.g., mitmproxy) to validate your configuration.

This lesson covered the common HTTP header types and examples for request, response, security, caching, CORS, proxy, and custom headers, plus useful NGINX variables and a sample configuration. Use these patterns to secure, optimize, and trace your web traffic.

Try these steps locally: configure response headers, set proxy headers in NGINX, and inspect requests and responses to observe effects on caching, security, and logging.

> **[Watch Video](https://learn.kodekloud.com/user/courses/nginx-for-beginners/module/8905470e-b1ea-48ec-b0cd-711687ce7159/lesson/889d65af-d23e-4813-98fb-afae795ba3e9)**


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.