Consent Mode v2 is now a hard requirement for running Google's advertising products in the EU, EEA, and UK. The documentation is scattered across half a dozen Google sources, and most implementations get it wrong in ways that aren't immediately visible — the tags appear to fire, the data looks plausible, and the bug only surfaces when a compliance review or a GA4 audit reveals that consent signals are either arriving too late or not at all.
This guide covers the GTM-specific implementation path: the Consent Initialization trigger, the Consent Mode API commands, the correct tag firing order, and the exact configuration that makes GA4 and Google Ads respond correctly to your banner's grant and deny signals.
How Google Consent Mode Works in GTM
Consent Mode v2 works through the gtag('consent', ...) API, which takes two commands:
- default — sets the initial consent state before the user interacts with your banner. Called once, on every page load, before any other tags fire.
- update — called when the user makes a choice. Updates the consent state and signals Google's tags to either activate fully (granted) or continue in modeling mode (denied).
The two new consent types added in v2 (on top of the v1 types) are ad_user_data and ad_personalization. If you only implement v1 (analytics_storage + ad_storage), Google Ads tags will not send user data for enhanced conversions, and you are not compliant with the CMP requirements that Google's EU consent policy mandates.
GTM handles both commands through two different trigger types: the Consent Initialization trigger (for the default command) and a Custom Event trigger (for the update command, fired by your banner's callback).
Step 1: Set the Consent Default
The consent default must fire before any other tags — including your GA4 configuration tag. GTM has a dedicated trigger for this: Consent Initialization. It fires before the Initialization trigger, which itself fires before Page View. Nothing fires before Consent Initialization.
To set the default in GTM:
- Create a new tag → Tag type: Consent Overview (or use a Custom HTML tag if you prefer the direct gtag API)
- Set the trigger to Consent Initialization — All Pages
- Configure all six consent types to
denied:
gtag('consent', 'default', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
functionality_storage: 'denied',
security_storage: 'granted',
wait_for_update: 500
});
The wait_for_update parameter (milliseconds) tells Google's tags to wait up to 500ms for a consent update before falling back to the default state. This is critical for returning visitors whose consent is stored in a cookie — without it, the tags fire in denied mode before your banner has had a chance to read the cookie and call the update command. Set it too high and you delay tag execution for everyone; 500ms is a safe ceiling for most CMP implementations.
Set security_storage to granted — this covers cookies necessary for security features (CSRF tokens, reCAPTCHA), which are legitimate interest and do not require consent under most interpretations of the GDPR e-privacy rules.
Step 2: Restore Consent from Cookie for Returning Visitors
When a returning visitor loads the page, your CMP should read their stored consent choice and fire the update command before the wait_for_update timer expires. If this doesn't happen, the visitor will see the default denied state applied — their tags run in modeling mode even though they previously consented.
How to wire this in GTM:
- Your CMP's script (loaded via a Custom HTML tag on Consent Initialization) should read the consent cookie on every page load and push a dataLayer event:
dataLayer.push({ event: 'consent_update', analytics_storage: 'granted', ... }) - A GTM trigger on
consent_updatefires a Custom HTML tag that callsgtag('consent', 'update', {...})with the stored values - For new visitors who haven't made a choice, the CMP does not push the event — so the default denied state holds until the banner interaction
If you're using a certified CMP (Cookiebot, OneTrust, Consentmanager, Usercentrics) via GTM's Consent Overview tag, many CMPs handle this automatically by integrating with GTM's native consent API. Check your CMP's GTM integration guide — if it says "automatic mode" or "native GTM integration," the cookie read + gtag update is handled for you. If it says "manual mode" or "Custom HTML," you need to wire the dataLayer push yourself.
Step 3: Fire the Consent Update on Banner Interaction
When a user clicks "Accept all" or "Decline" in your banner, your CMP must fire the gtag update command. In GTM, this is a Custom HTML tag triggered by a Custom Event fired by your banner's callback.
A minimal Custom HTML tag for the update:
<script>
(function() {
var analytics = {{DLV - consent.analytics}} === 'granted' ? 'granted' : 'denied';
var ads = {{DLV - consent.ads}} === 'granted' ? 'granted' : 'denied';
gtag('consent', 'update', {
analytics_storage: analytics,
ad_storage: ads,
ad_user_data: ads,
ad_personalization: ads
});
})();
</script>
Where {{DLV - consent.analytics}} and {{DLV - consent.ads}} are Data Layer Variables set by your banner's dataLayer push. The pattern of mapping ads → ad_user_data + ad_personalization is correct: if a user declines ad storage, they've also declined user data and personalization.
After the update command fires, Google's tags respond immediately. GA4 starts sending full event data. Google Ads sends conversion data including enhanced conversions. No page reload is required.
Step 4: Confirm Tag Consent Settings
Each Google tag in your GTM container has an Advanced Settings section with a "Consent settings" field. This defines which consent type(s) the tag requires before it fires. Google's built-in tag templates (GA4, Google Ads Conversion Tracking, Floodlight) now set these automatically. Custom HTML tags do not.
For Custom HTML tags that send analytics data, set: Requires: analytics_storage. For ad tags: Requires: ad_storage AND ad_user_data. If you leave this empty on a Custom HTML tag, it fires regardless of consent state — a compliance gap that an automated GTM Preview Mode session won't flag (because the tag fires), but that a GTM audit will catch.
GTM's built-in Consent Overview report (Workspace → Consent) shows which tags in your container have consent settings and which don't. Tags without consent settings that handle personal data are a compliance risk — they will fire even when all consent types are denied.
Verifying the Implementation in Preview Mode
The correct verification sequence in Consent Mode v2 is:
- Open GTM Preview. In the event timeline, confirm Consent Initialization is the first event — before Initialization and Page View
- In the Data Layer tab for the Consent Initialization event, confirm you can see the consent default being set with all types denied (except security_storage)
- Without accepting the banner, check the Tags tab for Page View: GA4 configuration should be listed as Tags Not Fired or should appear with a consent-denied indicator if it's set to require analytics_storage
- Click "Accept all" in your banner. A new event should appear in the timeline — the consent_update push. Check that it immediately triggers your update tag
- After acceptance, GA4 should move to Tags Fired for subsequent events
The most common failure mode: the banner's Accept callback fires too late — after Page View — and the GA4 configuration tag fires in denied mode for the first page. In that case, the session data for the first page is modeled, not measured. Fix: ensure the CMP script loads as early as possible (ideally via a Custom HTML tag on Consent Initialization, not on Page View) and that the banner is rendered before the main content paints.
Five Implementation Mistakes That Break Consent Mode
1. Not Setting a Default
Consent Mode without a default command does nothing. If you only call the update command (when the user clicks Accept), the consent state before that click is undefined — Google's tags run as if Consent Mode were not configured, which means they send full data before any consent is given. Always set a default, always set it to denied.
2. Using the Wrong Trigger for the Default Tag
If your consent default tag fires on the Initialization trigger or Page View trigger instead of Consent Initialization, other tags can fire before the default is set. On a slow connection where GTM takes a moment to load triggers, the race is real and reproducible. The Consent Initialization trigger exists precisely to prevent this — always use it for the default command.
3. Missing the New v2 Consent Types
A Consent Mode v1 implementation sets only analytics_storage and ad_storage. This was sufficient before 2024. It is not sufficient now. Google requires ad_user_data and ad_personalization to be set for EU traffic or Google's ad tags will not function correctly in the EU — and Google will not certify your CMP as compliant with its EU consent policy. Set all four ad-related types.
4. Forgetting the Cookie Restore for Returning Visitors
A new visitor lands, accepts the banner, you call the update command — this works. The same visitor returns tomorrow: if your CMP doesn't read the cookie and call the update command within the wait_for_update window, they are treated as a new denier on every return visit. Your GA4 consent rate will look lower than it is, and your ads will under-measure returning converter traffic. Always restore consent from the stored cookie on page load.
5. Missing Consent Settings on Custom HTML Tags
Every Custom HTML tag that handles personal data needs a "Requires consent" setting matching the consent type it depends on. Tags without this setting fire regardless of consent state. This is the most common gap in GTM containers that have been incrementally updated over several years — the Consent Mode settings were added to GTM's interface in 2022, and older Custom HTML tags predate the setting.
FAQ
Does Consent Mode affect my GA4 data quality?
Yes — but not negatively, as long as it's configured correctly. When a user denies analytics_storage, GA4 uses behavioral modeling to estimate their contribution to aggregated metrics. This is better than either (a) not having the data at all, or (b) collecting it without consent. For sites with high consent rates (>70%), the modeled data is directionally accurate. For sites with low consent rates, the modeling helps fill in what would otherwise be blind spots in your reporting.
Do I need Consent Mode if I'm not running Google Ads?
If you only have GA4 and no advertising tags, you are only handling analytics data — not ad data. The GDPR still requires consent for analytics cookies under most interpretations, but Google's specific Consent Mode v2 mandate (with the new ad_user_data and ad_personalization types) is primarily a requirement for accessing advertising features like enhanced conversions and audiences for remarketing. That said, implementing Consent Mode v2 for GA4 alone is still good practice and does not hurt — it future-proofs your setup.
What happens to GA4 data when consent is denied?
When analytics_storage is denied, GA4 does not write any first-party cookies. No client_id, no session_id. It can still receive event pings with cookieless signals (user agent, IP truncated for modeling purposes), but it will not identify returning visitors or stitch sessions together. In the GA4 interface, these sessions appear as modeled data rather than observed data. The shield icon in Explorations that indicates sampling is different from this — denied-consent modeling happens at the property level in standard reports.
How do I test consent mode is working in production?
The definitive test: open GA4 Admin → DebugView. With the debug parameter active in your browser (?gtm_debug=x), decline the banner and check whether GA4 DebugView shows events arriving. If it shows full events with client_id and session_id — Consent Mode is broken and your tags are firing unrestricted. If it shows no events or modeled-only events — Consent Mode is working. Then accept the banner and confirm events start appearing fully. For the GTM container itself, the Consent Initialization event in Preview Mode is the fastest confirmation path.
Free GTM audit
NiceLookingData's automated GTM audit checks your container's Consent Mode v2 configuration — whether the default is set, whether the new v2 consent types are present, whether Custom HTML tags have the right consent settings, and whether your consent tag fires on the correct trigger. 44 checks, free to run.
Run the GTM audit free →Analytics consultant turned founder. After years running the same GA4 and GTM audits across client engagements, Ludde built the audit into a product — so the pattern-matching takes a minute, not a meeting. More about Ludde →
Check your GTM container.
Upload your GTM export or connect live. Our auditor checks 44 best practices and gives you actionable fixes.
