Skip to main content
HTML Validation

Bad value “Expires” for attribute “http-equiv” on element “meta”.

About This HTML Issue

The http-equiv attribute on the <meta> element is designed to simulate certain HTTP response headers directly in HTML. However, the HTML specification only permits a specific set of values: content-type, default-style, refresh, x-ua-compatible, and content-security-policy. Using Expires as a value for http-equiv will trigger a validation error because it falls outside this permitted set.

Historically, some older browsers and HTML versions were more lenient about which values could appear in http-equiv, and developers commonly used <meta http-equiv="Expires" content="0"> or similar patterns to try to prevent page caching. However, this approach was never reliable — browsers and caching proxies handle actual HTTP headers far more consistently than <meta> tag equivalents. Modern HTML formally disallows this value.

Beyond standards compliance, there are practical reasons to avoid this pattern. Many browsers simply ignore unrecognized http-equiv values, meaning the tag does nothing useful. Cache behavior is best controlled at the HTTP level, where servers, CDNs, and proxies all read and respect the headers. Relying on a <meta> tag for caching gives a false sense of control while cluttering your markup with invalid code.

To fix this issue, remove the <meta http-equiv="Expires" ...> tag from your HTML and configure the Expires or Cache-Control HTTP header on your web server.

Examples

Incorrect: Using Expires in http-equiv

This triggers the validation error:

<head>
  <meta charset="UTF-8">
  <meta http-equiv="Expires" content="0">
  <meta http-equiv="Expires" content="Tue, 01 Jan 2025 00:00:00 GMT">
  <title>My Page</title>
</head>

Correct: Remove the invalid <meta> tag

Simply remove the offending tag. Only use valid http-equiv values:

<head>
  <meta charset="UTF-8">
  <title>My Page</title>
</head>

Correct: Valid uses of http-equiv

For reference, here are examples of valid http-equiv values:

<head>
  <meta charset="UTF-8">
  <meta http-equiv="refresh" content="30">
  <meta http-equiv="content-security-policy" content="default-src 'self'">
  <meta http-equiv="default-style" content="main-stylesheet">
  <title>My Page</title>
</head>

Correct: Set cache expiration via server configuration

The proper way to control caching is through HTTP response headers configured on your server.

Apache (.htaccess or server config):

<IfModule mod_expires.c>
  ExpiresActive On
  ExpiresByType text/html "access plus 1 day"
</IfModule>

Or using Cache-Control with mod_headers:

<IfModule mod_headers.c>
  Header set Cache-Control "no-cache, no-store, must-revalidate"
  Header set Expires "0"
</IfModule>

Nginx:

location ~* \.html$ {
  expires 1d;
  add_header Cache-Control "public, no-transform";
}

To prevent caching entirely in Nginx:

location ~* \.html$ {
  expires -1;
  add_header Cache-Control "no-store, no-cache, must-revalidate";
}

If you don’t have access to server configuration, many server-side languages let you set headers programmatically. For example, in PHP:

<?php
header("Expires: Tue, 01 Jan 2030 00:00:00 GMT");
header("Cache-Control: public, max-age=86400");
?>

By handling cache expiration at the server level, you get reliable behavior across all browsers, proxies, and CDNs — while keeping your HTML clean and standards-compliant.

Find issues like this automatically

Rocket Validator scans thousands of pages in seconds, detecting HTML issues across your entire site.

Help us improve our guides

Was this guide helpful?

Ready to validate your sites?
Start your trial today.