Content-Security-Policy-Report-OnlyContent-Security-Policy-Report-Only tells the browser not to actually enforce a CSP but to report what violations would have occurred had it been enforced. It is a 'dry-run' mode for safely observing side effects before applying a policy in production.
Its syntax and directives are identical to Content-Security-Policy, but on a violation it does not block the resource; it only logs a console warning and sends a violation report to report-to (or the legacy report-uri). This lets you experiment with a strong policy (e.g. removing unsafe-inline, introducing nonces) against real user traffic and learn in advance which inline scripts or third parties would break.
The recommended rollout is: (1) start in Report-Only with a lenient policy, (2) analyze reports to sort out exceptions, nonces, and hashes, and (3) once violations disappear, promote the same policy to an enforcing Content-Security-Policy. You can also send both headers at once, running an enforcing CSP while CSP-Report-Only observes a stricter next-step policy in parallel.
Reports are delivered via the Reporting API. Modern browsers send them to a group defined by the Reporting-Endpoints header, which the report-to directive names. The legacy report-uri path uses a separate CSP-specific report format still supported by some browsers but on the way out.
Content-Security-Policy-Report-Only: <directive> <source-list>[; ...]; report-to <group>e.g. Content-Security-Policy-Report-Only: default-src 'self'; script-src 'self' 'nonce-r4nd0m'; report-to csp-endpoint
<CSP directives> | Uses the same directives as regular CSP (default-src, script-src, frame-ancestors, etc.) but only reports violations instead of enforcing. |
report-to <group> | The Reporting-Endpoints group name to send violation reports to; essential in report-only mode. |
report-uri <url> | Legacy reporting: URL to POST violation reports to (now superseded by report-to). |