Request header
> Cookie: session=abc123; theme=darkCookie Header
Learn how the Cookie header sends stored cookies to servers with each request. Understand cookie transmission, session management, and security considerations.
- Direction
- Request
- Category
- Cookies
- Spec
- RFC 6265 §5.4
- JS can set it
- No: forbidden header name
On this page
- What is Cookie?
- How Cookies Work
- Cookie Format
- Single Cookie
- Multiple Cookies
- With Special Characters
- Common Use Cases
- Session Management
- User Preferences
- Shopping Cart
- Analytics and Tracking
- Real-World Examples
- E-commerce Site
- Social Media Platform
- Banking Application
- Cookie Attributes (Set by Server)
- HttpOnly
- Secure
- SameSite
- Expiration
- Security Considerations
- Sensitive Data Protection
- CSRF Protection
- Size Limitations
- Browser Behavior
- Automatic Sending
- Domain and Path Matching
- Cookie Jar Management
- Server-Side Handling
- Reading Cookies
- Setting Cookies
- Parsing Cookie Header
- Getting Cookie right
- Minimize Cookie Size
- Use Appropriate Attributes
- Handle Missing Cookies
- Testing Cookies
- Using curl
- Using JavaScript
- Cookie Size Limits and Cookie Prefixes
- Related Headers
TL;DR: Sends stored cookies from browser to server for session management and user tracking. Contains name=value pairs separated by semicolons for state persistence.
What is Cookie?
The Cookie header sends previously stored cookies back to the server. It’s like showing your membership card or loyalty points when you visit a store—the server recognizes you and remembers your preferences.
Cookies enable stateful interactions in the stateless HTTP protocol, allowing servers to remember users across requests.
How Cookies Work
1. Server sets cookies:
HTTP/1.1 200 OK
Set-Cookie: sessionId=abc123; HttpOnly; Secure
Set-Cookie: theme=dark; Max-Age=86400
2. Browser stores and sends them back:
GET /dashboard HTTP/1.1
Host: example.com
Cookie: sessionId=abc123; theme=dark
Cookie Format
Single Cookie
Cookie: name=value
Multiple Cookies
Cookie: sessionId=abc123; userId=42; theme=dark; lang=en
With Special Characters
Cookie: message=Hello%20World; data=%7B%22key%22%3A%22value%22%7D
Common Use Cases
Session Management
Cookie: JSESSIONID=A1B2C3D4E5F6; PHPSESSID=xyz789
Maintains user login state across requests.
User Preferences
Cookie: theme=dark; language=en-US; timezone=America/New_York
Remembers user settings and customizations.
Shopping Cart
Cookie: cart=item1,item2,item3; cartTotal=49.99
Tracks items before user logs in.
Analytics and Tracking
Cookie: _ga=GA1.2.123456789; _gid=GA1.2.987654321
Google Analytics tracking cookies.
Real-World Examples
E-commerce Site
GET /products HTTP/1.1
Host: shop.example.com
Cookie: sessionId=user123; cart=prod1,prod2; currency=USD; lastVisit=2026-01-17
Social Media Platform
GET /feed HTTP/1.1
Host: social.example.com
Cookie: authToken=jwt123; userId=42; notifications=enabled; darkMode=true
Banking Application
GET /account HTTP/1.1
Host: bank.example.com
Cookie: secureSession=encrypted123; csrfToken=abc456; lastActivity=1642518000
Cookie Attributes (Set by Server)
HttpOnly
Set-Cookie: sessionId=abc123; HttpOnly
Prevents JavaScript access (XSS protection).
Secure
Set-Cookie: authToken=xyz789; Secure
Only sent over HTTPS connections.
SameSite
Set-Cookie: csrf=token123; SameSite=Strict
Controls cross-site request behavior.
Expiration
Set-Cookie: remember=true; Max-Age=2592000
Set-Cookie: temp=data; Expires=Wed, 20 Jan 2027 12:00:00 GMT
Security Considerations
Sensitive Data Protection
// ❌ Don't store sensitive data in cookies
document.cookie = 'password=secret123'
document.cookie = 'creditCard=1234567890123456'
// ✅ Store session identifiers only
document.cookie = 'sessionId=abc123; Secure; HttpOnly'
CSRF Protection
Cookie: csrfToken=random123; sessionId=user456
Include CSRF tokens to prevent cross-site attacks.
Size Limitations
// Cookies are limited to ~4KB per cookie
// Total limit: ~4KB per domain
const largeCookie = 'data=' + 'x'.repeat(4000) // Might be rejected
Browser Behavior
Automatic Sending
Browsers automatically include relevant cookies:
GET /api/profile HTTP/1.1
Host: example.com
Cookie: sessionId=abc123; theme=dark
# Browser adds these automatically
Domain and Path Matching
# Cookie set for .example.com applies to:
# - example.com
# - www.example.com
# - api.example.com
# Cookie set for /admin applies to:
# - /admin
# - /admin/users
# - /admin/settings
Cookie Jar Management
// Browsers manage cookie storage automatically
// Cookies persist across browser sessions (unless session-only)
// Expired cookies are automatically removed
Server-Side Handling
Reading Cookies
// Node.js/Express
app.get('/profile', (req, res) => {
const sessionId = req.cookies.sessionId
const theme = req.cookies.theme || 'light'
if (!sessionId) {
return res.status(401).json({ error: 'Not authenticated' })
}
const user = getUserBySession(sessionId)
res.json({ user, theme })
})
Setting Cookies
// Express.js
res.cookie('sessionId', 'abc123', {
httpOnly: true,
secure: true,
maxAge: 24 * 60 * 60 * 1000 // 24 hours
})
Parsing Cookie Header
function parseCookies(cookieHeader) {
const cookies = {}
if (cookieHeader) {
cookieHeader.split(';').forEach((cookie) => {
const [name, value] = cookie.trim().split('=')
cookies[name] = decodeURIComponent(value)
})
}
return cookies
}
Getting Cookie right
Minimize Cookie Size
// ❌ Large cookies slow down requests
Cookie: userData = {
name: 'John',
email: 'john@example.com',
preferences: { theme: 'dark', lang: 'en' }
}
// ✅ Store minimal identifiers
Cookie: sessionId = abc123
Use Appropriate Attributes
// For authentication
res.cookie('sessionId', id, {
httpOnly: true,
secure: true,
sameSite: 'strict'
})
// For preferences
res.cookie('theme', 'dark', { maxAge: 30 * 24 * 60 * 60 * 1000 }) // 30 days
// For tracking (if needed)
res.cookie('analytics', id, { secure: true, sameSite: 'lax' })
Handle Missing Cookies
app.get('/api/data', (req, res) => {
const sessionId = req.cookies.sessionId
if (!sessionId) {
return res.status(401).json({
error: 'Authentication required',
redirectTo: '/login'
})
}
// Continue with authenticated request
})
Testing Cookies
Using curl
# Send cookies manually
curl -H "Cookie: sessionId=abc123; theme=dark" https://example.com/api/profile
# Save cookies from response
curl -c cookies.txt https://example.com/login
# Use saved cookies
curl -b cookies.txt https://example.com/dashboard
Using JavaScript
// Read cookies (if not HttpOnly)
const cookies = document.cookie.split(';').reduce((acc, cookie) => {
const [name, value] = cookie.trim().split('=')
acc[name] = value
return acc
}, {})
// Set cookies (client-side)
document.cookie = 'theme=dark; max-age=86400; secure'
Cookie Size Limits and Cookie Prefixes
Browsers enforce size limits on cookies. A single cookie is limited to about 4096 bytes, and browsers drop larger ones silently. Per-domain count limits are around 180 in Chrome and Firefox (the old figure of 50 is obsolete). Cookies over the limit are silently dropped, which causes subtle login bugs. Everything the browser sends back in the Cookie header also counts against the server’s request-header limits, which is where 431 Request Header Fields Too Large and nginx’s 400 Request Header Or Cookie Too Large come from; the request header too large guide shows how to find the oversized cookie.
Cookie prefixes are a security mechanism that enforces attribute requirements. A cookie named __Secure-session must have the Secure attribute — browsers reject it otherwise. A cookie named __Host-session must have Secure, must not have a Domain attribute, and must have Path=/. The __Host- prefix is the stronger of the two because it prevents subdomain cookies from overriding it, making it ideal for session cookies on applications that share a domain with other services.
Related Headers
- Set-Cookie - Server sets cookies
- Authorization - Alternative authentication
- User-Agent - Client identification
- Referer - Request origin tracking
Frequently asked questions
What is the Cookie header?
The Cookie header sends stored cookies from the browser to the server. It contains name=value pairs for all cookies that match the request domain and path.
How are multiple cookies sent?
Multiple cookies are sent in one header, separated by semicolons: "Cookie: session=abc; theme=dark; user=123". Each cookie is a name=value pair.
What is the difference between Cookie and Set-Cookie?
Cookie is a request header sent by clients. Set-Cookie is a response header sent by servers to create or update cookies. They work together for state management.
Why are my cookies not being sent?
Check cookie attributes: domain must match, path must match, Secure requires HTTPS, SameSite may block cross-site requests, and HttpOnly cookies are still sent but not accessible to JavaScript.
Sources
Related
Cookies vs localStorage vs sessionStorage: What to Use
Cookies vs localStorage vs sessionStorage: request behavior, size limits, expiry, tab scope, partitioning, XSS and CSRF risks, and auth token choices.
Proxy-Authorization Header
Learn how Proxy-Authorization provides credentials to access resources through a proxy server. Understand proxy authentication schemes and security.
Set-Cookie Header: Attributes, Examples and Browser Rules
Set-Cookie syntax and every attribute: Expires, Max-Age, Domain, Path, Secure, HttpOnly, SameSite, Partitioned, __Host- prefixes, with Express and Django.
Authentication-Info Header
Learn how Authentication-Info provides additional authentication data in responses to successful requests. Covers digest authentication and session info.
Authorization Header: Bearer, Basic and 401 Fixes
Authorization header carries credentials as scheme plus token. Bearer and Basic formats, WWW-Authenticate, why proxies strip it, redirects, CORS and storage.