Content Security Policy (CSP) is a list, sent by the site, of where scripts, styles, images and connections are allowed to come from. When something isn't on the list, the browser blocks it and logs an error naming the rule it broke. That rule, the directive, tells you exactly what to change.
Refused to load the script 'https://cdn.example.com/widget.js' because it violates the
following Content Security Policy directive: "script-src 'self'".
You can't fix a policy until you know who sends it. Check both places:
Content-Security-Policy. It may be set by your server code, a framework (Helmet for Express, Next.js config, Django settings), your web server, a CDN, or your host's security settings.<meta http-equiv="Content-Security-Policy" content="...">.If both exist, the browser enforces both: something must pass each one. A Content-Security-Policy-Report-Only header never blocks anything; it only reports, and its console messages say "[Report Only]".
The script's origin isn't allowed. Add it to script-src:
Content-Security-Policy: script-src 'self' https://cdn.example.com
If there's no script-src, the browser uses default-src, and the error will name that instead. Add the origin to script-src (creating it) rather than loosening default-src for everything.
Tag managers and widgets often load more scripts from other domains. Each shows up as its own error; add the ones you trust, one at a time.
Refused to execute inline script because it violates the following Content Security Policy
directive: "script-src 'self'". Either the 'unsafe-inline' keyword, a hash
('sha256-B2yPHKaXnvFWtRChIbabYmUBFZdVfKKXHbWtWidDVF8='), or a nonce ('nonce-...') is required
to enable inline execution.
Code inside <script> tags and onclick= attributes is blocked. In order of preference:
<script src="/app.js">, and swap onclick="..." for addEventListener.script-src 'nonce-r4nd0m' and <script nonce="r4nd0m">.script-src. Any edit to the script changes the hash.'unsafe-inline' makes the error go away by switching off CSP's main protection against injected scripts. Inline event handlers can't use nonces at all, so move them to addEventListener. If you truly can't change that markup, 'unsafe-hashes' plus the handler's hash allows just those exact handlers: much weaker than moving them, much stronger than 'unsafe-inline'.
Something called eval(), new Function(), or setTimeout with a string. Usually it's a library: older template engines, some chart and validation libraries, or a development build with eval-based source maps. Switch to a production build or a CSP-compatible version before adding 'unsafe-eval'.
The same rules for CSS, under style-src. Inline style= attributes and <style> blocks need a nonce, a hash or 'unsafe-inline'. Many CSS-in-JS libraries inject styles at runtime and support a nonce; check their docs. Google Fonts needs style-src https://fonts.googleapis.com and font-src https://fonts.gstatic.com.
fetch, XHR, WebSocket and EventSource calls are governed by connect-src. Add your API's origin, and wss:// origins for WebSockets:
connect-src 'self' https://api.example.com wss://live.example.com
This is different from a CORS error. CSP is your page refusing to send the request; CORS is the other server not permitting your page to read the answer. CORS error messages are here.
Add the origin to img-src or font-src. Images from data: URLs need img-src data:, and blob images need blob:.
Two different errors with similar wording:
frame-src.To prove CSP is the cause, or to try a third-party widget on a site you don't control, remove the policy in your own browser for that site only. Chrome has no setting for it, but a header extension can strip the Content-Security-Policy response header. It can't remove a <meta> policy, since that lives inside the page.
Has a ready-made "Remove Content-Security-Policy" rule you can limit to one site, switch off with one click, and check that it fired. Use it to test, then fix the real policy. No account, no tracking.
Get HeaderForge for ChromeRelated: HTTP headers list · X-Frame-Options · CORS errors.
More on this topic: Mixed content error: “loaded over HTTPS, but requested an insecure resource” · How to change your user agent in Chrome (and what it really changes) · ModHeader alternative · Requestly alternatives for modifying headers (2026)