HTTP

Header

Warning Header

Learn about the deprecated Warning header that provided additional status information about message transformations. Understand why it was removed from HTTP.

5 min read advanced Try in Playground

TL;DR: Deprecated header that provided additional message status information like stale cache content. Don’t use it—modern alternatives like Cache-Control and custom headers are better.

What is Warning?

The Warning header provides additional information about the status of a response that might not be reflected in the HTTP status code. It was commonly used by caches to indicate that a cached response might be stale, transformed, or otherwise not exactly what the origin server would provide.

Note: The Warning header is deprecated and has been removed from the HTTP specification. Modern applications should use other mechanisms (Cache-Control, custom headers, or response body) to communicate similar information.

Historical Usage

Cache serving stale content:

HTTP/1.1 200 OK
Age: 7200
Cache-Control: max-age=3600
Warning: 110 cache.example.com "Response is Stale"
Content-Type: application/json

{"data": "potentially outdated"}
```text

**Transformed response:**

```http
HTTP/1.1 200 OK
Warning: 214 proxy.example.com "Transformation Applied"
Content-Type: image/jpeg
Content-Encoding: gzip

[compressed image data]

Syntax

Warning: <warn-code> <warn-agent> "<warn-text>" ["<warn-date>"]
```text

- `warn-code`: Three-digit warning code
- `warn-agent`: Server/proxy that generated warning
- `warn-text`: Human-readable description
- `warn-date`: Optional date of warning

```http
Warning: 110 cache.example.com "Response is Stale"
Warning: 199 proxy.example.com "Miscellaneous Warning" "Wed, 21 Oct 2025 07:28:00 GMT"

Warning Codes

1xx - Warnings about Cache Freshness

# 110 - Response is Stale
Warning: 110 cache.example.com "Response is Stale"

# 111 - Revalidation Failed
Warning: 111 cache.example.com "Revalidation Failed"

# 112 - Disconnected Operation
Warning: 112 cache.example.com "Disconnected Operation"

# 113 - Heuristic Expiration
Warning: 113 cache.example.com "Heuristic Expiration"
```text

### 2xx - Warnings about Transformations

```http
# 214 - Transformation Applied
Warning: 214 proxy.example.com "Transformation Applied"

# 299 - Miscellaneous Persistent Warning
Warning: 299 proxy.example.com "Miscellaneous Persistent Warning"

Common Examples (Historical)

Stale Cache Response

HTTP/1.1 200 OK
Age: 5000
Cache-Control: max-age=3600
Warning: 110 cdn.example.com "Response is Stale"
Content-Type: application/json

{"data": "old data"}
```text

### Failed Revalidation

```http
HTTP/1.1 200 OK
Warning: 111 cache.example.com "Revalidation Failed"
Content-Type: text/html

<html>...</html>

Image Compression

HTTP/1.1 200 OK
Warning: 214 proxy.example.com "Image quality reduced"
Content-Type: image/jpeg

[compressed image]
```http

### Multiple Warnings

```http
HTTP/1.1 200 OK
Warning: 110 cache1.example.com "Response is Stale"
Warning: 214 proxy.example.com "Transformation Applied"
Content-Type: application/json

Why It Was Deprecated

1. Limited Adoption

// Rarely checked in client code
fetch('/api/data').then((response) => {
  const warning = response.headers.get('Warning')
  // Most apps never checked this header
})
```text

### 2. Better Alternatives Exist

```http
# Instead of Warning: 110 - use Cache-Control
Cache-Control: max-age=3600, stale-while-revalidate=86400

# Instead of Warning: 214 - use custom headers
X-Image-Quality: reduced
X-Transform-Applied: compression

# Or include in response body
{"data": "value", "meta": {"cached": true, "age": 3600}}

3. Ambiguous Semantics

# Warning didn't clearly indicate severity
Warning: 110 cache.example.com "Response is Stale"
# Should client retry? Use cached data? Unclear.
```text

## Modern Alternatives

### 1. Cache-Control Directives

```http
# Instead of Warning: 110 (stale)
Cache-Control: max-age=3600, stale-while-revalidate=86400, stale-if-error=172800

2. Custom Headers

# Custom headers for application-specific warnings
X-Cache-Status: STALE
X-Cache-Age: 7200
X-Transform-Applied: image-compression
X-Quality-Level: reduced
```text

### 3. Response Metadata

```json
{
  "data": { ... },
  "meta": {
    "cached": true,
    "age": 7200,
    "stale": true,
    "warnings": [
      "Response is stale by 3600 seconds",
      "Image quality reduced for mobile"
    ]
  }
}

4. Server-Timing Header

# For performance and debug information
Server-Timing: cache;desc="HIT";dur=0.5, db;dur=23.2
```javascript

## Migration Examples

### Before (with Warning)

```javascript
// Old code using Warning header
app.get('/api/data', async (req, res) => {
  const cachedData = await cache.get('data')

  if (cachedData && cachedData.isStale) {
    res.setHeader('Warning', '110 server "Response is Stale"')
  }

  res.json(cachedData.value)
})

After (modern approach)

// Modern approach with custom headers and metadata
app.get('/api/data', async (req, res) => {
  const cachedData = await cache.get('data')

  if (cachedData) {
    // Use custom headers
    res.setHeader('X-Cache-Status', cachedData.isStale ? 'STALE' : 'FRESH')
    res.setHeader('X-Cache-Age', cachedData.age.toString())

    // Or include in response
    res.json({
      data: cachedData.value,
      meta: {
        cached: true,
        stale: cachedData.isStale,
        age: cachedData.age
      }
    })
  } else {
    res.json({ data: await fetchFreshData() })
  }
})
```javascript

## Legacy Support

If you need to support legacy systems:

```javascript
// Support both Warning header and modern approach
app.get('/api/data', async (req, res) => {
  const cachedData = await cache.get('data')

  if (cachedData && cachedData.isStale) {
    // Legacy Warning header for old clients
    res.setHeader('Warning', '110 server "Response is Stale"')

    // Modern custom headers
    res.setHeader('X-Cache-Status', 'STALE')
    res.setHeader('X-Cache-Age', cachedData.age.toString())
  }

  res.json(cachedData.value)
})

Best Practices (for Modern Applications)

1. Don’t Use Warning Header

// ❌ Don't use deprecated Warning header
res.setHeader('Warning', '110 server "Response is Stale"')

// ✅ Use Cache-Control or custom headers
res.setHeader('X-Cache-Status', 'STALE')
```text

### 2. Use Cache-Control for Cache Issues

```javascript
// ✅ Modern cache directives
res.setHeader('Cache-Control', 'max-age=3600, stale-while-revalidate=86400')

3. Custom Headers for Application Logic

// ✅ Domain-specific headers
res.setHeader('X-Data-Quality', 'approximate')
res.setHeader('X-Processing-Status', 'partial')
```text

### 4. Include Warnings in Response Body

```javascript
// ✅ Structured warnings in JSON
res.json({
  data: result,
  warnings: [
    {
      code: 'STALE_DATA',
      message: 'Data is 2 hours old',
      severity: 'info'
    },
    {
      code: 'PARTIAL_RESULTS',
      message: 'Some fields unavailable',
      severity: 'warning'
    }
  ]
})

Historical Examples

CDN Cache Warning

# Old CDN response
HTTP/1.1 200 OK
Age: 4000
Cache-Control: max-age=3600
Warning: 110 cdn.cloudfront.net "Response is Stale"
X-Cache: Hit from cloudfront

# Modern equivalent
HTTP/1.1 200 OK
Age: 4000
Cache-Control: max-age=3600, stale-while-revalidate=86400
X-Cache: Hit from cloudfront
X-Cache-Status: STALE
```http

### Proxy Transformation

```http
# Old proxy response
HTTP/1.1 200 OK
Warning: 214 proxy.example.com "Image compressed"
Content-Type: image/jpeg

# Modern equivalent
HTTP/1.1 200 OK
X-Transform-Applied: compression
X-Original-Size: 2048576
X-Compressed-Size: 512000
Content-Type: image/jpeg

Testing (for Legacy Systems)

Check for Warning Header

# Using curl
curl -I https://legacy-api.example.com/data | grep -i warning

# Output (if present):
# warning: 110 cache "Response is Stale"
```javascript

### Parse Warning Header

```javascript
// Parse Warning header (legacy code)
function parseWarning(warningHeader) {
  if (!warningHeader) return null

  const match = warningHeader.match(/(\d{3})\s+(\S+)\s+"([^"]+)"/)

  if (match) {
    return {
      code: parseInt(match[1]),
      agent: match[2],
      text: match[3]
    }
  }

  return null
}

// Usage
const warning = parseWarning(response.headers.get('Warning'))
if (warning && warning.code === 110) {
  console.log('Warning: Response is stale')
}

Summary

The Warning header is deprecated and should not be used in modern applications. Instead:

  1. Use Cache-Control directives for cache-related information
  2. Use custom headers (e.g., X-Cache-Status) for application-specific warnings
  3. Include warning information in the response body as structured data
  4. Use Server-Timing for performance and debugging information

Frequently Asked Questions

What is the Warning header?

Warning carried additional information about message status, like stale cache content. It is deprecated in HTTP and should not be used in new implementations.

Why was Warning deprecated?

Warning was rarely implemented correctly and provided little practical value. Modern caching uses other mechanisms. It was removed from HTTP specifications.

What were common Warning codes?

110 Response is Stale, 111 Revalidation Failed, 112 Disconnected Operation, 113 Heuristic Expiration. These indicated cache-related conditions.

What should I use instead of Warning?

For cache status, use Age header and Cache-Status header. For general warnings, use appropriate status codes or custom headers with clear documentation.

Keep Learning