TL;DR: This breaks in two opposite directions and they get confused constantly. Analytics fires before consent (a compliance problem) is usually a hardcoded tag in your theme, a page builder injecting the script outside the consent layer’s reach, Google Tag Manager loading independently, or a cached page serving a stale consent state. Analytics stays blocked after consent (a data problem) is usually a script-handle mismatch after an update, Consent Mode set to denied with nothing flipping it, or a cache serving the pre-consent version. Confirm which one you have in a private window with the Network tab before changing anything, because the fixes are unrelated and guessing wastes an afternoon.
Two very different bugs share one description. Someone says “my cookie banner isn’t working with Google Analytics” and it turns out to mean either “GA fires before anyone clicks accept” or “GA never fires even after they do.”
The first is a compliance exposure. The second is a data outage where you’re probably underreporting traffic and drawing bad conclusions from it. Fixing the wrong one is common, so start by finding out which you have.
First: confirm what’s actually happening
Don’t trust your consent tool’s dashboard for this. Check the browser.
- Open a private or incognito window, so no stored consent cookie is in play.
- Open developer tools and go to the Network tab. Filter for
collect,gtag,analytics, orgoogletagmanager. - Load your site and do not touch the banner.
- Look at what fired.
If you see requests to google-analytics.com/g/collect or googletagmanager.com/gtag/js before you clicked anything, analytics is firing pre-consent. That’s problem one.
- Now click Accept and watch the same filter.
If nothing new appears after accepting, analytics is blocked post-consent. That’s problem two.
Also worth checking the Application tab under Cookies to see whether _ga and _ga_* are being set, and when. And repeat the whole thing with a VPN set to an EU country if your banner is geo-aware, because the behavior you get in Ohio is not the behavior a German visitor gets, and the bug may only exist in one of them.
Two things that will mislead you here: ad blockers block GA regardless of consent, so test with them off. And browser extensions can inject or strip scripts, so a clean profile is worth the thirty seconds.
Problem 1: analytics fires before consent
The tag is hardcoded in your theme
The most common cause by a distance. Someone pasted the GA snippet directly into header.php, a theme options “custom scripts” box, or a site-wide header injection field. Consent tools generally block scripts they know about, through their own script handles or a tag manager. A raw snippet in your theme header is invisible to that mechanism and just runs.
Check: view source and search for gtag, G-, or googletagmanager. If it’s sitting inline in the <head> rather than being loaded by your consent tool or analytics plugin, that’s it.
Fix: remove it from the theme and add GA through whatever your consent tool actually manages, whether that’s its own integration, a supported analytics plugin, or a properly gated tag manager.
A page builder is injecting it
Elementor, Divi, WPBakery, and similar tools have their own script-injection settings, and scripts added there can bypass a consent layer that only knows about WordPress’s enqueue system. Same root cause, different hiding place.
Check: look in your page builder’s global settings for custom code, header scripts, or integrations, and check per-page settings too, since a builder can inject on a single template.
Google Tag Manager is loading independently
GTM is a frequent culprit because it feels like it’s under control when it isn’t. If GTM loads unconditionally and your GA tag fires on a standard page-view trigger, GA runs regardless of what your banner does. The consent tool blocked its GA integration; GTM’s copy is separate.
Fix: either gate the GTM container itself behind consent, or use Google Consent Mode inside GTM so tags wait for a consent signal. Half-doing this is the usual state: Consent Mode configured but nothing actually updating the signal.
Caching is serving a stale state
A full-page cache can serve a visitor a version of the page generated for someone who had already consented. Aggressive caching plus geo-aware banners is genuinely difficult, because now the cache key has to include region as well as consent state, and most default configurations don’t.
Check: compare a hard refresh with cache disabled in dev tools against a normal load. Different behavior points here.
Fix: exclude consent-relevant pages from full-page caching, or configure the cache to vary on the consent cookie and region. This is fiddly and it’s where a lot of otherwise-correct setups fall down.
The banner is decorative
Worth stating: some banners were never blocking anything. If yours says “By continuing to use this site, you agree,” it’s likely a notice with no enforcement behind it, and nothing is misconfigured. It’s doing exactly what it was built to do, which is nothing. That framing also isn’t valid consent in the EU or UK, so this is a replacement rather than a fix. Does a small-business website need a cookie banner? covers when that matters.
Problem 2: analytics stays blocked after consent
This one is worse in a quiet way, because instead of an error you get a chart that trends down and a wrong conclusion about your marketing.
Script-handle mismatch after an update
Consent plugins block scripts by handle or by matching source URLs. A plugin update that renames a handle, or an analytics plugin that changes how it loads GA, leaves the consent tool blocking a script it no longer recognizes as the one to unblock. Everything looks configured correctly; the string just doesn’t match anymore.
Check: in your consent tool’s script or cookie settings, confirm the GA entry still matches what the site actually loads. Compare against the actual URL in the Network tab.
Consent Mode is denied and nothing updates it
With Google Consent Mode, GA loads but runs in a restricted state until analytics_storage is granted. If your banner never sends the update, GA is present, sending cookieless pings, and recording almost nothing useful. It looks like it’s working. It isn’t.
Check: in the console, look at dataLayer after accepting and confirm a consent update event with analytics_storage: 'granted' appears.
Caching, again
The same cache that can serve a pre-consent page to someone who consented. If accepting appears to do nothing but a hard refresh fixes it, this is your answer.
Consent recorded on the wrong scope
A consent cookie set on www.example.com won’t be read on example.com, and vice versa. If your site is reachable at both, or you have subdomains, a visitor can consent on one and be treated as unconsented on the other.
Check: in the Application tab, look at the domain scope of your consent cookie against the domain you’re actually browsing.
The pattern underneath all of this
Every cause above is an integration failure between two systems that don’t know about each other. The consent tool has a model of what your site loads. Your site actually loads something slightly different, because a theme, a builder, a tag manager, a cache layer, or an update changed something on one side without telling the other.
This is why these bugs are so often discovered months late. Nothing errors. The banner still appears, analytics still has a dashboard, and the number is just quietly wrong in one direction or the other.
The structural fix is to shrink the gap between the two models. Fewer script-injection points, one place tags are managed, and someone whose job is to check after updates.
How server-side consent avoids most of this
Worth explaining as a design difference rather than a pitch, because it clarifies why these bugs exist at all.
Most CMPs work client-side. The page is delivered with the tracking scripts present, and JavaScript prevents them from executing until consent arrives. That’s a race, and the failure modes above are all versions of the blocker and the tracker disagreeing about what’s on the page.
Surmado Sites decides on the server instead. The consent state is resolved before the page is rendered, so in opt-in regions the tracking script is never sent to the browser at all. There’s nothing to block, so there’s no blocker to fall out of sync, no handle to mismatch after an update, and no ad blocker or race condition in the path. Consent state is part of what determines the page, so the caching interaction is handled rather than left to configuration.
It’s also why our banner is deliberately narrow: accept or decline, one category, no scanner. Surmado is not a consent management platform and doesn’t offer cookie discovery, a preference center, consent records, generated policies, DSAR handling, or Consent Mode v2. If you need those, one of the tools in our category breakdown is the better buy. What the server-side approach removes is the class of bug this entire post is about.
Quick diagnostic checklist
Run these in order:
- Private window, Network tab, filter
collect. Load without touching the banner. Anything fire? - View source and search for
gtag/G-/googletagmanager. Hardcoded in the theme? - Check page builder global and per-page custom code settings. Injected there?
- Is GTM loading unconditionally? Is Consent Mode configured and actually updated?
- Click accept, watch the Network tab. Does GA fire now?
- Hard refresh with cache disabled. Different behavior? That’s caching.
- Application tab, check the consent cookie’s domain scope against the URL you’re on.
- Repeat with a VPN in an EU country if your banner is geo-aware.
Most cases resolve at step 2 or step 4.
The bottom line
Establish direction first: firing before consent is a compliance problem, staying blocked after consent is a data problem, and they share no fixes. Then work the list, because these are integration bugs and integration bugs live in the seams between systems, not inside them.
If you keep finding new seams, the consent tool probably isn’t the thing to change. Best WordPress cookie consent plugins covers the plugin-level options and what breaks with each, and best cookie consent tools for small businesses covers the whole category. If the answer is that you’d rather not own the seams, Surmado Sites rebuilds your existing site with tracking and consent built together, and sends you a preview before you pay anything. Pricing is on the pricing page.
Technical guidance, not legal advice. Whether your setup meets your obligations depends on where you operate and what you collect.