Refused to execute inline script medium
"Refused to execute inline script because it violates the following Content Security Policy directive"
A Content-Security-Policy script-src directive without 'unsafe-inline' blocked an inline <script> or event handler.
What you see
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-...'), or a
nonce ('nonce-...') is required to enable inline execution. What’s actually happening
A feature breaks — a button does nothing, a widget never initializes, analytics stop firing — and the browser console shows the refusal in red. It only affects inline code: <script> blocks written directly in the HTML and on* attributes like onclick. External .js files referenced with src load fine. The page itself renders; only the inline JavaScript is dead.
Common causes
- The CSP script-src (or default-src) lists sources but omits 'unsafe-inline', which is the default-deny behavior for inline code
- An inline <script>...</script> block embedded in the HTML
- An HTML event-handler attribute such as onclick=, onload=, or onerror=
- A third-party tag (ad, chat, A/B test) that injects inline script after load
- A javascript: URL in an href or form action, which CSP also treats as inline
How to fix it
- Move the code into an external fileCut the inline JavaScript into its own .js, serve it from an origin already in script-src (or 'self'), and reference it with <script src>. Replace onclick="foo()" with addEventListener in that file. This is the cleanest fix and needs no CSP change.
- Add a per-request nonce if the script must stay inlineGenerate a fresh random nonce on every response, put it in the header as script-src 'nonce-RANDOM', and add nonce="RANDOM" to the <script> tag. The nonce must be unguessable and regenerated each request — a static nonce is the same as 'unsafe-inline'.
- Whitelist the exact script by SHA-256 hashFor a fixed inline block you don't control by template, hash its exact bytes and add 'sha256-...' to script-src. The console message usually prints the expected hash. Any change to the script content breaks the hash, so this fits static snippets only.
- Avoid 'unsafe-inline' unless nothing else worksAdding 'unsafe-inline' makes the error vanish but removes the XSS protection CSP exists to provide. If you must use it as a stopgap, scope it narrowly and treat it as tech debt. Note that a nonce or hash in the same directive causes browsers to ignore 'unsafe-inline'.
Stop it recurring
Deploy CSP in Content-Security-Policy-Report-Only mode first and collect violation reports, so you catch every inline script before the policy enforces.
Related errors