In short. A CSP error in the console means the page's security policy (the Content-Security-Policy header) refused to load or run a resource — most often a script, a style, or a request to another domain. You read it one directive at a time: the message states which directive fired (script-src, style-src, connect-src…) and which source was blocked. You fix it in two ways: allow the needed source in that directive — or, more safely, move inline code into a separate file, or sign it with a nonce/hash instead of 'unsafe-inline'. Below is how to parse the message and pick the right fix without weakening protection.
What a CSP error is
Content-Security-Policy is a header with which a site tells the browser where scripts, styles, images, and fonts may be loaded from, and where requests may be sent. Anything the policy doesn't allow, the browser blocks and writes an error to the console. This isn't a site breakage but the protection firing: CSP is one of the strongest barriers against XSS. How to set the policy up from scratch is in the CSP setup guide; here it's about reading and fixing the errors.
A CSP error isn't a bug but a fuse that tripped. Before you "allow everything," ask: why did the policy block the resource? Often the right answer isn't to weaken the policy but to bring the code into line with it.
How to read the message
A typical console error (F12) looks like this:
Refused to execute inline script because it violates the following
Content Security Policy directive: "script-src 'self'".
Either the 'unsafe-inline' keyword, a hash (...), or a nonce (...) is required.
Breaking it down:
- What was blocked — "Refused to execute inline script" (inline script), "Refused to load the stylesheet" (style), "Refused to connect" (a fetch/XHR request).
- Which directive fired —
script-src 'self': the policy allows scripts only from your own domain. - What's suggested — add a source, or use a
nonceorhashinstead of inline.
The directive in the message is the key: it tells you which resource type met which rule.
| Directive | What it controls | Common cause of the error |
|---|---|---|
| script-src | Where scripts load and run from | Inline <script>, a third-party CDN, eval() |
| style-src | Styles and inline style= | Inline styles, font CDNs |
| connect-src | Where fetch/XHR/WebSocket may go | A request to an API on another domain |
| img-src / font-src | Images and fonts | An external image/font host |
How to fix it — the right way
An inline script or style is blocked
The message asks for 'unsafe-inline', but adding it is a bad solution: it opens the door to the very XSS that CSP exists to stop. Instead:
- Move the code into a separate file (
.js/.css) on your own domain — then'self'covers it and no inline is needed. - Or sign the inline with a nonce/hash: the server adds a one-time
nonce(or a hash of the content) to the allowed block, and only that runs. This allows the specific code without opening up all inlines.
# a policy with a nonce (the server generates a new one per request):
Content-Security-Policy: script-src 'self' 'nonce-Ab3xZ...'
# and in the HTML:
<script nonce="Ab3xZ...">...</script>
A third-party script or style is blocked (CDN)
If it's a trusted source (say, your analytics script), add its domain to the right directive: script-src 'self' https://cdn.example.com. Don't allow more than needed — specific hosts only, not *.
An error on eval()
A message about 'unsafe-eval' means the code (or a library) uses eval() / new Function(). The best solution is to replace such code; adding 'unsafe-eval' is a last resort, and only with the risk understood.
A fetch/XHR request is blocked
The connect-src directive doesn't allow the domain the request goes to. Add it: connect-src 'self' https://api.example.com.
The rule for choosing: first try to bring the code into line with the policy (move inline out, drop eval), and only if the source is genuinely needed and trusted, allow exactly it. "Allowing everything" via'unsafe-inline'or*kills the point of CSP.
How to debug safely
So you don't break a live site while tuning the policy, use Content-Security-Policy-Report-Only mode: the browser doesn't block resources but only reports violations. That way you collect every problem without breaking anything, then switch on the enforcing policy. It's convenient to check the final policy and its directives with the CSP analyzer — it parses the header and shows what each directive allows. A general breakdown of directives is in the CSP guide; on signing third-party resources, see the article on Subresource Integrity.
Frequently asked questions
Can I just add 'unsafe-inline' and forget it?
Technically yes, the error will vanish — but you'll disable CSP's main protection against XSS. That's acceptable only as a temporary crutch. The right way is to move inline into files or use a nonce/hash; then there are no errors and the protection works.
The error is only in the console, the site seems to work. Does it matter?
Yes. It means some resource is being blocked — possibly part of the functionality (analytics, a widget, a style) isn't working, it's just not always visible. Go through each message: either the resource is needed (allow the source correctly), or it's superfluous (then remove its call).
How do I know exactly which policy line is at fault?
The console message always states the directive in quotes ("script-src 'self'") — that's the guilty rule. Run the header through the CSP analyzer, find that directive, and decide: add a source or fix the code.
Checklist to remember
- A CSP error = protection that fired: the policy blocked a resource, not "the site broke."
- The message always names a directive (
script-src,connect-src…) — that's the guilty rule. - Fix inline by moving it into a file or with a nonce/hash, not
'unsafe-inline'. - For a third-party source, allow the specific host, not
*. - Tune via
Report-Onlyto collect violations without breaking anything.