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

> Canonical HTML version: https://rocketvalidator.com/html-validation/bad-value-expires-for-attribute-http-equiv-on-element-meta
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

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:

```html
<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:

```html
<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:

```html
<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):

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

Or using `Cache-Control` with `mod_headers`:

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

**Nginx**:

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

To prevent caching entirely in Nginx:

```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
<?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.
