Since March 2024, Consent Mode v2 has been mandatory for any advertiser running ads in the EU/EEA. Most teams “implement” it by installing a CMP (Cookiebot, Complianz, Usercentrics, CookieYes) and calling the job done. The banner shows up. Legal is happy. Marketing assumes the analytics side is fine because GA4 still receives events.
It isn't fine. The most common failure is not a missing banner — it's a CMP that shows the banner but never fires the gtag('consent', 'update') call after the user accepts. GA4 keeps sending pageviews in the default “denied” state, Google Ads never receives modeled conversions, and your paid attribution quietly collapses.
What Consent Mode v2 Actually Does
Consent Mode v2 is a signal layer between your site and Google's tags. It sets four flags — ad_storage, analytics_storage,ad_user_data, ad_personalization — and updates them when the user answers the banner. Google's tags (GA4, Google Ads) read those flags on every request.
| Flag state | What GA4 sends | What Google Ads gets |
|---|---|---|
| Default: denied | Cookieless pings — no client_id, no session continuity | No conversion linkage; entire user path invisible |
| Update: granted | Full events with client_id and session state | Full conversion linkage via gclid + cookies |
| Update: denied (explicit) | Cookieless pings that Google uses for behavioral modeling | Modeled conversions (up to 30–60% recovery in DE/FR/NL) |
The critical word is update. Default flags without a subsequent update look identical to “the user hasn't answered yet.” Google's modeling doesn't kick in on pure default state — it kicks in on explicit denies. When your CMP never fires the update, every user looks like they're still deciding forever, and nothing is modeled.
The Symptom Pattern
We've seen this exact profile in four EU audits this quarter. The client reports:
- GA4 shows 30–60% of sessions as Direct / (none) or Unassigned
- Google Ads reports N conversions, GA4 shows 30–50% of N
- Real-time report looks fine on desktop, worse on mobile
- The CMP dashboard shows an acceptance rate of 70–85%
That last line is what gives the pattern away. If 80% of users accept and GA4 still misses half your paid conversions, it's not the users declining — it's the acceptance signal not reaching gtag.
gtag('consent', 'update') call never fired. GA4 kept sending cookieless pings for the entire session. Fix deployed in an inline snippet the same day — attribution gap dropped from 60% to 18% within a week.How to Detect the Gap in 90 Seconds
Chrome → DevTools → Network → filter collect. Load your homepage. Look at the outgoing GA4 requests. Check the gcs parameter. gcs=G100 means both storage flags denied.gcs=G101 means analytics denied, ads granted.gcs=G111 means both granted.
Watch the Network tab. A new collect request should fire immediately with gcs=G111. If no new collect request fires, or if the gcs value stays at G100, your CMP is not firing the consent update.
GA4 Admin → DebugView. Trigger events after accepting. Every event should show ad_storage: granted and analytics_storage: granted in its parameters. If they show denied even after acceptance, the gap is confirmed.
This test takes 90 seconds and catches the vast majority of Consent Mode v2 gaps. If gcs upgrades from G100 to G111 after Accept, your CMP is working. If it doesn't change, you have the exact problem this article describes.
The Four Fixes That Actually Work
1. Add an Explicit gtag Consent Update Bridge
The safest fix is an inline snippet that listens for the CMP's acceptance event and calls gtag('consent', 'update') directly. Every mainstream CMP dispatches an event when consent changes — Cookiebot fires CookiebotOnAccept, Complianz fires cmplz_status_change, Usercentrics fires uc:cmp:consent-updated. Wire that event to a gtag update and the bridge is closed.
denied. Then attach a listener on the CMP's change event. When the event fires, read the CMP's per-category state (marketing, analytics, personalization) and map it to the four Consent Mode flags. Call gtag('consent', 'update', {...}). Do this before any other conversion pixel — Meta, TikTok, LinkedIn all read the same signal chain.2. Switch to the CMP's Google-Native Integration
Cookiebot, Usercentrics, and OneTrust all ship a “Google Consent Mode v2 template” that must be enabled in the CMP dashboard. It's disabled by default in most installs. Turning it on will make the CMP call gtag directly instead of only setting its own cookie.
Complianz has this off by default too — the toggle is called “Enable Google Consent Mode” in Complianz → Integrations. Turn it on. Save. Test again with the 90-second procedure above.
3. Move Consent Mode Higher in Your Tag Order
Consent Mode must load before gtag.js. If your GTM container loads the GA4 tag on Page View — All Pages, and your CMP loads on a later trigger, the first GA4 hit fires with default flags and never gets updated because gtag has already sent it. Set the CMP script inline in the <head>, above GTM. Set the Consent Mode default state in the same inline block.
4. Verify Modeling Is Actually Being Applied
Once explicit accept and deny both flow correctly, check that Google is modeling. GA4 → Admin → Property Settings → Consent Settings shows the modeling status. It requires a minimum traffic threshold (roughly 1,000 users per day per country over 28 days). If your account is under threshold, modeling won't start — the gap will remain until volume grows or you consolidate reporting properties.
The Four-Flag Mapping Nobody Explains
Even teams that know Consent Mode v2 exists get the flag mapping wrong. Here's the mapping that actually matches Google's intent:
| Flag | Controls | Map to CMP category |
|---|---|---|
ad_storage | Google Ads cookies (gclid, _gcl_aw) | Marketing / Advertising |
analytics_storage | GA4 cookies (_ga, _ga_XXX) | Statistics / Analytics |
ad_user_data | Sending user data to Google for ads | Marketing / Advertising (same as ad_storage) |
ad_personalization | Personalized ads / remarketing eligibility | Marketing / Advertising (same as ad_storage) |
The two new flags introduced in v2 — ad_user_data and ad_personalization — must both be set. Missing them is functionally equivalent to declined consent for Google Ads modeling. Most CMPs still don't map these correctly unless you enable their v2 template explicitly.
Diagnosis Checklist
Why This Matters More in 2026 Than 2024
When Consent Mode v2 launched in 2024, EEA modeling recovered maybe 15–25% of lost conversions. In 2026 that recovery has climbed to 45–60% in high-refusal markets like Germany, France, and the Netherlands — Google's model has had two years of training data. The teams still leaving Consent Mode broken are giving up close to a full third of their measurable performance to a snippet gap.
This is also the single most common thing we find in a first-week tracking audit for any EU advertiser. If your GA4/Ads gap is above 30% and your acceptance rate is above 70%, run the 90-second test today. The rest of the framework — and the Google Ads side of the same problem — is covered in the Sterling Lab blog, or see how we approach tracking rebuilds in conversion tracking audits.