net::ERR_BLOCKED_BY_CLIENT (request blocked client-side)
The browser — not your server — blocked a resource, almost always an ad blocker or privacy extension matching it against a filter list.
What you see
This site can't be reached example.com refused to connect. ERR_BLOCKED_BY_CLIENT
What’s actually happening
The giveaway is the word "client": the block happened inside the visitor's browser, not on your server. Something installed on their machine — uBlock Origin, AdBlock Plus, Brave's shields, a privacy extension, or a parental-control tool — matched the request against a filter list and killed it. The server never saw the request, so there's nothing in your access logs. You usually see it on a single blocked file (an analytics script, an ad slot, a tracking pixel) in DevTools while the rest of the page loads fine. It's frequently a false positive: filter lists match on URL substrings, so a path or class name containing "ad," "banner," "track," or "promo" gets caught even when it's your own code.
Common causes
- An ad blocker (uBlock Origin, AdBlock Plus) matched the resource URL against EasyList or a similar filter list
- A privacy/anti-tracking extension blocked an analytics, pixel, or tracking script (Google Analytics, Facebook Pixel, Hotjar)
- A false-positive substring match — your own file or element named like an ad, e.g. /js/ad-slot.js, /track.js, or a div with class "banner-ad"
- Brave browser shields or a built-in blocker stripping third-party requests
- A parental-control or endpoint-security tool on the device filtering the request
How to fix it
- Reproduce with extensions offOpen the page in an Incognito window (extensions are disabled there by default) or a clean profile. If the resource loads, the cause is confirmed client-side — an extension, not your server. This is the fastest way to stop chasing a server bug that doesn't exist.
- Find which file is blocked in DevToolsOpen DevTools -> Network, reload, and look for the request marked (blocked:other) or showing ERR_BLOCKED_BY_CLIENT in red. The URL tells you what tripped the filter — usually a third-party tracker or a file whose name pattern-matches an ad.
- Rename your own false-positive resourcesIf it's your code getting caught on a name, rename it. /js/ad-slot.js becomes /js/slot.js; a class of "banner-ad" becomes "promo-unit" without the blocked token; an /ads/ directory becomes /sponsored/. Filter lists key on these substrings, so dropping the trigger word fixes it for every blocked visitor at once.
- Don't depend on blockable third-party scripts for core functionIf a feature breaks when analytics or a pixel is blocked, that's a design problem — a large share of users run blockers. Load tracking asynchronously and make the page work without it. Never gate content or navigation behind a script that an ad blocker will kill.
- Accept it for genuine trackersIf the blocked request really is Google Analytics or an ad network, there's nothing to fix and nothing broken for the visitor — they chose to block tracking. Your job is only to make sure the site still works when they do.
Stop it recurring
Keep core functionality off blockable third-party scripts, and avoid naming files, paths, or CSS classes with ad/track/banner tokens that filter lists match on.