Troubleshooting blocked scripts
The console errors a script-src violation produces and how to fix each one, from blocked inline scripts to eval and strict-dynamic issues.
When script-src blocks a script, the browser writes a console message that
names the reason. This page maps the common messages to their fix.
"Refused to execute inline script"
Full message: Refused to execute inline script because it violates the following Content Security Policy directive.
The page has an inline <script> and your policy does not allow inline
execution. Pick one:
- Add a nonce to the tag and the header.
- Add the script's hash to the header.
- Move the code into an external file served from an allowed host.
Adding 'unsafe-inline' also silences it, but see
unsafe keywords for why that removes your protection.
"Refused to execute inline event handler"
This is the same class of error for an attribute like onclick="…". Inline
event handlers are covered by script-src-attr, which falls back to
script-src. The clean fix is to move the handler into a script:
<!-- blocked -->
<button onclick="save()">Save</button>
<!-- allowed: attach the listener from a nonced or hashed script -->
<button id="save">Save</button>
<script nonce="r4nd0m">
document.getElementById('save').addEventListener('click', save);
</script>
"Refused to load the script 'https://…'"
An external script's host is not in the source list. Add the host, or if you use
'strict-dynamic', load it from a script that is
already trusted by a nonce or hash rather than by host.
"Refused to evaluate a string as JavaScript"
Your code calls eval, new Function, or setTimeout with a string, and
'unsafe-eval' is not present. Prefer to remove the string-to-code call. If it
comes from a dependency you cannot change yet, add 'unsafe-eval' as a tracked,
temporary allowance. For WebAssembly only, use 'wasm-unsafe-eval' instead.
A nonce is present but the script is still blocked
Check each of these:
- The
nonceattribute value matches the header value exactly. - The header nonce is different on every response. A cached page can serve a stale nonce that no longer matches.
- You are reading the enforced header, not a
Content-Security-Policy-Report-Onlyheader, which reports but does not block.
strict-dynamic did not allow a child script
'strict-dynamic' only propagates trust to scripts created through the DOM API,
such as document.createElement('script'). Scripts injected with
document.write or innerHTML stay blocked by design. If a loader relies on
document.write, it will not work under 'strict-dynamic'.
See what is actually being blocked in production
Console errors only show what you happen to hit while testing. To capture every violation across real traffic, turn on violation reporting.