# Content-Security-Policy HTTP header: Bad content security policy

> Canonical HTML version: https://rocketvalidator.com/html-validation/content-security-policy-http-header-bad-content-security-policy
> Attribution: Rocket Validator (https://rocketvalidator.com)
> License: CC BY 4.0 (https://creativecommons.org/licenses/by/4.0/)

Content Security Policy (CSP) is a security mechanism that lets you control which resources a browser is allowed to load for your page. When defined via a `<meta http-equiv="Content-Security-Policy">` tag, the validator checks whether the `content` attribute contains a well-formed policy. If the policy string contains unrecognized directives, malformed source expressions, or syntax errors, the validator reports "Bad content security policy."

Common causes of this error include:

- **Misspelled directive names** — e.g., `script-scr` instead of `script-src`.
- **Invalid source values** — e.g., using `self` without single quotes (it must be `'self'`).
- **Using directives not allowed in `<meta>` tags** — the `frame-ancestors`, `report-uri`, and `sandbox` directives are not supported when CSP is delivered via a `<meta>` element.
- **Incorrect separators** — directives are separated by semicolons (`;`), not commas or pipes.
- **Missing or extra quotes** — keywords like `'none'`, `'self'`, `'unsafe-inline'`, and `'unsafe-eval'` must be wrapped in single quotes. Conversely, hostnames and URLs must *not* be quoted.

This matters because a malformed CSP may be silently ignored by browsers, leaving your site without the intended protection against cross-site scripting (XSS) and data injection attacks. Even a small typo can cause an entire directive to be skipped, creating a security gap you might not notice.

### How to fix it

1. **Check directive names** against the [CSP specification](https://w3c.github.io/webappsec-csp/). Valid fetch directives include `default-src`, `script-src`, `style-src`, `img-src`, `font-src`, `connect-src`, `media-src`, `object-src`, `child-src`, `worker-src`, and others.
2. **Wrap keyword values in single quotes**: `'self'`, `'none'`, `'unsafe-inline'`, `'unsafe-eval'`, and nonce/hash sources like `'nonce-abc123'`.
3. **Separate directives with semicolons**. Multiple source values within a single directive are separated by spaces.
4. **Avoid directives that are invalid in `<meta>` tags**. If you need `frame-ancestors` or `report-uri`, deliver CSP via an HTTP header instead.
5. **Don't include the header name inside the `content` attribute**. The `content` value should contain only the policy itself.

## Examples

### ❌ Misspelled directive and unquoted keyword

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src self; script-scr https://example.com">
```

Here, `self` is missing its required single quotes, and `script-scr` is a typo for `script-src`.

### ✅ Corrected directive name and properly quoted keyword

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src https://example.com">
```

### ❌ Using a directive not allowed in a `<meta>` tag

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; frame-ancestors 'none'">
```

The `frame-ancestors` directive is ignored in `<meta>` elements and may trigger a validation warning.

### ✅ Removing the unsupported directive from the `<meta>` tag

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'">
```

Deliver `frame-ancestors` via an HTTP response header on your server instead.

### ❌ Using commas instead of semicolons between directives

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self', script-src 'none', style-src 'self'">
```

### ✅ Using semicolons to separate directives

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; script-src 'none'; style-src 'self'">
```

### ❌ Quoting a hostname (hostnames must not be in quotes)

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; img-src 'https://images.example.com'">
```

### ✅ Hostname without quotes

```html
<meta http-equiv="Content-Security-Policy"
  content="default-src 'self'; img-src https://images.example.com">
```

When in doubt, use an online CSP evaluator to validate your policy string before adding it to your HTML. This ensures both syntactic correctness and that the policy actually enforces what you intend.
