Pixels Blocked by an Ad Blocker or CSP? How to Tell
How do you tell if an ad blocker or CSP is blocking your pixels?
Open Chrome DevTools and reload the page. A request an ad blocker stopped fails with net::ERR_BLOCKED_BY_CLIENT; one your own Content Security Policy stopped shows as “(blocked:csp)” in the Network panel, with a Console error naming the directive. A consent tool looks different again: the tag sends nothing, or only a cookieless ping, until the visitor agrees.
The difference decides who can fix it. A blocker is the visitor’s choice, your Content Security Policy (CSP) is your site’s own rule, and a consent tool does what you set it to do. If you haven’t yet confirmed that the tag fires at all, first check whether a pixel is working. Every source cited here was checked on 25 September 2026.
What does each kind of block look like?
Each cause leaves a different trace in Chrome DevTools and has a different owner. Read the Network panel’s Status column and the Console together.
| Cause | Network panel | Console | Who can fix it |
|---|---|---|---|
| An ad-blocking or privacy extension | The request in red, listed under Blocked requests | net::ERR_BLOCKED_BY_CLIENT |
The visitor |
| A DNS filter or VPN on the visitor’s device or network | “(failed)” with a name-resolution or connection error, such as net::ERR_NAME_NOT_RESOLVED |
The same error | The visitor, or whoever runs their network |
| Your CSP | The request in red, with the status “(blocked:csp)” | An error such as “Connecting to ‘…’ violates the following Content Security Policy directive”, naming the directive: script-src, connect-src or img-src, for example. The Issues panel lists it too |
You, or whoever sets your site’s headers |
| A consent tool holding the tag | No request until the visitor agrees; Google’s tags in advanced consent mode send cookieless pings instead | Usually nothing | You, in your banner’s settings |
| The platform’s script never loaded | The script’s own request failed or is missing, so no event requests follow | Often an error from code that expected the script | Whoever installed the tag |
| The platform refused the event | The request went out and came back with a 4xx status | Usually nothing | The tag’s set-up: start with the platform’s own tool |
Sources: Chrome’s Network reference for “(failed)”, red rows and the Blocked requests filter; the Issues panel for CSP violations; Chrome’s source code for its error list, Console load errors, CSP messages and which errors DevTools counts as blocked; DevTools’ own test for the “(blocked:csp)” status; Google’s consent mode overview for basic and advanced mode.
Look for the platform’s script before its events. A blocker or a CSP that stops the script, such as Meta’s fbevents.js, stops the events that depend on it: no event request is made, so the Network panel shows one failed or blocked script and then silence, which is easy to misread as a tag that never triggered.
To list only what was stopped, choose More filters → Blocked requests in the Network panel. A DNS failure won’t show there, because Chrome marks it “(failed)”, and nor will a consent hold, because nothing was sent: for that, check that Google Consent Mode is working.
What does ERR_BLOCKED_BY_CLIENT mean?
Something inside the browser cancelled the request before it left the device, usually an ad-blocking or privacy extension. Chrome’s own error list describes it as “The client chose to block the request.” It isn’t an error your site returned.
To confirm the block is in your browser rather than on your site:
- Open the page in an Incognito window. Extensions run there only if you allowed them to (Chrome Enterprise Help).
- Open the Network panel, reload and repeat the action.
- If the request now succeeds, an extension in your normal window was blocking it. Turn extensions off one at a time to find which.
- For future tests, allow your own site in that extension, or keep a separate Chrome profile with no blocker installed, so your checks see what an unblocked visitor’s browser sends.
On a work computer you may see net::ERR_BLOCKED_BY_ADMINISTRATOR instead: Chrome uses it for addresses on a block list set by the organisation’s administrator.
All Pixel Helper, which we build, marks a request blocked when Chrome reports it blocked, but it can’t tell an ad blocker from a CSP, and a CSP-blocked request may not appear in it at all. Chrome’s own panel is the tool for this.
How much of your traffic blocks your tags?
You can’t measure it from the tags themselves, because a blocked tag reports nothing, not even that it was blocked. Measure the gap instead: your own records against what each platform received.
- Compare like with like. Take orders or sign-ups from your own system and the platform’s count of the same event, over the same days in the same time zone.
- Don’t compare against another tag. Your analytics tag may be blocked by the same lists as your ad pixels, so it can’t serve as the baseline. Orders can.
- Rule out the other causes. Declined consent, attribution windows and a broken tag all widen the gap too. For Meta on Shopify, those are covered in Meta pixel not tracking purchases.
- Count what the platform received, not what it credited. A platform’s ad reports show only conversions it attributed to an ad; that difference is attribution, not blocking (tracking gap or attribution gap).
- Know what a server copy changes. A purchase sent from your server never passes through the visitor’s browser, so their blocker can’t stop it, but it still needs their consent. More in what server-side tracking fixes.
Treat any fixed percentage of “blocked traffic” with suspicion. It depends on your visitors’ devices, extensions and consent choices, and only your own comparison tells you yours.
How do you fix a Content Security Policy that blocks Tag Manager?
Give the Tag Manager snippet a nonce, allow the domains each Google product needs, then allow the domains of every other vendor your container loads. Google’s guide, Use Tag Manager with a Content Security Policy, lists the directives; it was last updated on 18 September 2026.
- Add a nonce. Have your server generate a new, unguessable nonce for each response, put it in the
script-src-elemdirective asnonce-…, and set the same value on the Tag Manager snippet’snonceattribute. Tag Manager then passes the nonce on to the scripts it adds to the page. - Allow Google’s domains. GA4’s are in the table below. Google Ads conversion and remarketing tags add
https://www.googleadservices.com,https://googleads.g.doubleclick.netand others to several directives. Tag Manager’s Preview mode needs its own list too, includinghttps://tagmanager.google.com. - Decide on Custom JavaScript variables. Under a CSP they return
undefinedunlessscript-srcincludes'unsafe-eval'. Google advises using it only when absolutely necessary and recommends Custom Templates instead. - Allow every other vendor. Each non-Google tag your container loads needs its own domains. Meta’s pixel, for example, loads
fbevents.jsfromconnect.facebook.netand sends events towww.facebook.com(Meta: pixel base code). Take the list from each vendor’s own documentation. - Check the result. When your CSP blocks something, Tag Assistant lists the resources your policy blocked. Tag Diagnostics reports Content Security Policy blocks some resources when essential tag resources are blocked (Google: Tag Diagnostics). Google also suggests CSP’s reporting directives, so that violations in visitors’ browsers are reported to you.
| Directive | Sources Google lists for Google Analytics without any Ads features |
|---|---|
script-src-elem |
https://www.googletagmanager.com |
img-src |
https://www.googletagmanager.com https://*.google-analytics.com |
connect-src |
https://www.googletagmanager.com https://*.google-analytics.com https://*.google.com |
Google’s main Google Analytics list is longer: it adds the endpoints that Ads features use, including *.g.doubleclick.net, a frame-src entry and each Google country domain you need, listed one by one because CSP allows no wildcard at the end of a hostname. Google recommends the longer list from the start, so the policy needn’t change if you link Google Ads later.
Should you try to get around ad blockers?
No. Don’t rename, disguise or proxy tags to slip past a visitor’s blocker or consent choice. Those are choices the visitor made about their own browser.
The platforms offer a different route for browser events that never arrive: a server-to-server API alongside the pixel, such as Meta’s Conversions API or TikTok’s Events API. It sends events you already hold, such as the purchase in your order records, and it is still bound by the consent each visitor gave or refused, as noted above.
Frequently asked questions
Why does Tag Manager’s Preview say it can’t connect?
Often because something stops Tag Assistant or the Google tag. Google’s troubleshooting steps include checking whether a CSP blocks the Google tag, and warn that consent tools can block Google tags (Google: Tag Assistant). Preview also needs its own entries in your CSP, as step 2 above says. More causes are in Google tag not detected.
Does an ad blocker stop conversions reaching Meta?
Browser events, yes, when it blocks Meta’s script or requests. Meta itself asks you to switch off your ad blocker so its own extension can detect the pixel (Meta: Ads Data Advisor). A purchase sent from a server isn’t affected by the visitor’s blocker, though it still needs their consent.
Is ERR_BLOCKED_BY_CLIENT a fault on my site?
Usually not. It comes from the browser that shows it, normally from an extension its user installed. If you see it in your own browser, test in Incognito before changing anything on your site. If your customers’ browsers produce it, that is their choice: measure the gap, don’t work around it.