Tag debugging
If your tags stopped firing after a security update and the analytics team is blaming the dev team, your Content Security Policy is the most likely culprit. CSP is a browser security header that controls which scripts, connections, and images a page is allowed to load, and it blocks analytics tags as readily as it blocks attackers.
The frustrating part is how quiet the failure is. The page loads. Nothing looks broken. But Google Tag Manager never initialises, GA4 never sends a hit, and your Meta pixel goes dark. Conversions slide in the reports and nobody can point to a single thing that changed, because the only evidence is buried in the browser console.
A Content Security Policy is an HTTP response header. It lists, per resource type, the origins a page may load from. Anything not on the list is refused. The directives that trip up analytics are:
script-src: controls which scripts can run. Miss www.googletagmanager.com here and the entire GTM container, plus every tag inside it, never loads.connect-src: controls fetch, XHR, and beacon calls. This is where GA4 actually sends data, and where a server-side first-party endpoint lives. Miss it and tags load but no data leaves the browser.img-src: controls images, including the tracking pixels older platforms still rely on.frame-src: controls iframes, which some consent tools and tag templates inject.So a policy can fail in two very different ways: the tag never loads (a script-src problem), or the tag loads but its data never sends (a connect-src problem). They look identical in your reports and completely different in the console.
CSP violations are the textbook silent failure. There is no error page, no failed deploy, no alert. The console logs a Refused to load or Refused to connect message, but on a busy site that line is lost among dozens of unrelated warnings. The policy may only apply to certain pages, so the problem looks intermittent. And if the team uses Content-Security-Policy-Report-Only, violations are reported but not enforced, which means the policy you test is not the policy that ships.
This is exactly the kind of issue an analytics audit exists to find, and it is why I stopped debugging it by hand.
I built CSP Detector, a Chrome extension that surfaces Content Security Policy and CORS violations in real time, while you browse the site you are debugging. Instead of scrolling the console, you get:
script-src, connect-src, img-src, and the rest), with the blocked origin called out.'unsafe-inline'.It runs on Manifest V3, requests only what it needs to read network and console errors, and keeps everything local to your browser. I built it because I kept losing afternoons to tag deployments that broke behind a strict policy, and the console was never fast enough to tell me why.
The fix is almost always to allowlist the right origins in the right directive. A policy that lets a standard GA4 and GTM setup work looks roughly like this:
Content-Security-Policy:
script-src 'self' https://www.googletagmanager.com;
img-src 'self' https://www.google-analytics.com https://*.google-analytics.com;
connect-src 'self' https://www.google-analytics.com https://*.analytics.google.com
https://www.googletagmanager.com;
A few rules of thumb that save the most time:
script-src and the data endpoints in connect-src. Forgetting the second is the most common reason a tag loads but never reports.connect-src, or the whole point of moving server-side is lost to a blocked request.'unsafe-inline'. Use a nonce or hash for the small inline snippets a tag manager needs, so you keep the security benefit CSP is there for.CSP problems cluster around exactly the work that matters most: server-side migrations, consent and tag governance, and any site where security and marketing ship on different schedules. A consent banner tightens the policy, a security review adds a header, a new pixel needs an origin nobody allowlisted, and the data quietly degrades.
If your conversions dropped without an obvious cause, do not assume the tracking code is wrong. Check whether the page is allowed to run it at all.
script-src directive that does not include https://www.googletagmanager.com blocks the GTM container script from loading, which stops every tag inside it. The page itself loads fine, so the failure is easy to miss.script-src (https://www.googletagmanager.com) and the data endpoints in connect-src (https://www.google-analytics.com and https://*.analytics.google.com). If you collect through a server-side container, add that first-party endpoint to connect-src too.CH·01 · Contact
If your numbers slid after a security or consent change, a free health check will tell you whether a blocked tag is the cause, and exactly which directive to fix.
Free Analytics Health Check →