The shape of the failure
Consent Mode v2 is Google's way of passing each visitor's cookie consent to its tags. The failures these seven checks catch are silent. The site keeps loading. The banner keeps showing. Analytics keep reporting something. The failures reveal themselves weeks later, when someone compares platform numbers to warehouse numbers and the gap is too large to hand-wave.
These failures don't look like failures. A broken consent configuration does not throw console errors, does not return 500s, and does not visibly change the site. Pageviews still fire. Events still flow. The numbers look plausible.
What breaks is the signal quality underneath. Tags fire before the consent defaults are set, so hits that should have been held back, or sent as cookieless pings in advanced mode, go out as full ones. Conversions sent server-side arrive without a consent state because it was never propagated, and Google warns those conversions may not be attributable. Google's Smart Bidding quietly bids down campaigns that look like they've stopped converting, and when the break is site-wide, that's all of them at once.
By the time a reconciliation catches the break, weeks of bidding and budget decisions have been made on bad data. Most of the commercial damage is in that decision lag, not the reporting gap itself.
The checks below are written for a Google-centric stack: GTM, GA4, Google Ads, and Meta via its Conversions API (CAPI). The principles translate directly to server-side setups (sGTM, Elevar, Addingwell, Stape) and to Meta and TikTok pixel-led configurations, with vendor-specific consent hooks in place of gtag.
This check is written against UK and EU requirements (UK GDPR and PECR, EU GDPR and the ePrivacy Directive). It's calibrated to France's CNIL, which fined Shein €150 million in September 2025 for cookies placed without consent. The seven checks apply directly under Quebec's Law 25 and are safer-than-required under Canadian PIPEDA, other provincial Canadian acts, and US state privacy laws such as CCPA/CPRA. If a deployment serves visitors in any UK or EU market, the default-deny posture below is not optional. For multi-market deployments, default-deny satisfies every jurisdiction this article addresses.
Check 01: Consent defaults fire before GTM
When the defaults live in the page HTML, the script that sets them must execute before the GTM container loader. If GTM loads first, any tag inside it that respects Consent Mode v2 will initialise with no consent state declared. Google tags treat that as implicitly granted, so they fire normally and send full-behaviour hits that should have been gated.
In view-source, the order should be: gtag('consent', 'default', {...}) script block, then the GTM loader (function(w,d,s,l,i){...}) block. If the order is reversed, move the consent defaults into a blocking script before the GTM snippet.
One way this fails: a CMP tag inside GTM sets the defaults on an ordinary page-view trigger, which can execute too late. Inside GTM, the defaults belong on the Consent Initialization - All Pages trigger, which fires before every other tag.
Check 02: All four consent-sensitive types are denied by default
Consent Mode v2 has four consent-sensitive types, and for UK and EEA visitors all four must be denied in the default state:
ad_storageanalytics_storagead_user_data(new in Consent Mode v2, November 2023)ad_personalization(new in Consent Mode v2, November 2023)
Two more types can be granted by default because they cover non-consent-requiring processing:
functionality_storage(language preferences, session persistence)security_storage(fraud prevention, abuse detection)
If ad_user_data or ad_personalization is missing, the setup is still on Consent Mode v1 and is non-compliant: Google has required both signals for EEA traffic since March 2024. Every configuration deployed before that date needs reviewing.
Check 03: wait_for_update is present in defaults
The wait_for_update parameter tells Google's tags to hold for a specified number of milliseconds before sending data, giving a banner that loads asynchronously time to apply the visitor's choice. Without it, tags fire immediately on page load with the default denied state, so in advanced mode a returning visitor who has already accepted sends their first hits as cookieless pings.
500ms is a sensible default. Shorter risks races with slow-loading banner scripts; longer delays the first hits from Google's tags whenever the banner is slow to respond.
Check: the defaults call should include 'wait_for_update': 500. If absent, add it. If set to 0 or a very low value, raise it.
Check 04: The banner actually calls gtag consent update on accept
A consent banner can set a cookie or local storage value on accept and never call gtag('consent', 'update', {...}). The cookie is set, the banner dismisses, and the site appears to be working. Tags remain gated in their default denied state, even for visitors who accepted.
This check requires actually clicking Accept on the staging banner and watching what happens in GTM Preview mode. Open the Consent tab (next to Summary, Variables, Data Layer) and select an event that fired after the click. The On-page Update column should show the relevant consent types transitioning from "denied" to "granted".
If the update column stays empty, the banner is cosmetic. On a custom-built banner, the fix is a one-line addition to the accept handler.
Check 05: No unexpected tags firing pre-consent
In GTM Preview mode on the staging site, before clicking the consent banner, check the Tags Fired panel. On a well-configured site the only tags firing before consent should be Google's own tags (sending cookieless pings, in advanced consent mode), any consent tag on the Consent Initialization trigger, and strictly functional tags.
If Meta Pixel, TikTok Pixel, LinkedIn Insight Tag, Reddit Pixel, or other third-party marketing tags are firing before consent is granted, the site is non-compliant. Each tag needs consent gating added inside GTM, via built-in consent checks (for tags that support Consent Mode v2), the "Require additional consent for tag to fire" setting, or a blocking trigger tied to a consent state variable.
The failure mode: tags were copied in from an older container or a different property where consent gating wasn't configured, and nobody audited them on the new environment.
Check 06: The GTM container ID is production, not staging
This check feels too obvious to miss, which makes it easy to skip. It matters most on domain migrations and environment copies.
In view-source on the staging site, search for the GTM container ID in the GTM snippet. Confirm it matches the intended production container. If the staging environment is serving the staging container (for pre-production testing), confirm the production deployment pipeline replaces it with the production ID on release.
The failure to look for: the staging environment keeps serving the staging GTM container after it's been promoted to production, because the container ID was hardcoded in a template rather than injected from environment config. Every tag inside the staging container continues to fire on production pageviews, which at best sends bad data to a test property and at worst sends production visitor data to a container that isn't hardened for live traffic.
Check 07: Environment flags match the deployment target
A CMP account can hold several configurations: development, staging, production, and occasionally per-market variants. OneTrust, for example, generates a test script and a production script for each website. Each configuration has its own script URL, and its categorisation rules and banner behaviour can differ from the others.
The staging environment should load the staging CMP script during pre-production testing. The production environment must load the production CMP script after release. A staging CMP script running in production will apply staging rules, and if staging is set to a stricter default-deny, it blocks tags the production configuration would allow.
Check: view-source on the staging site, find the CMP script URL, and confirm whether the path or parameter indicates staging or production. On the production deployment, repeat the check after release.
Running the check
Block 15 minutes before any production release that touches tracking. Open GTM Preview mode connected to the staging URL. Work through the seven checks in order. Document any failures and fix them before release.
The asymmetry of cost and benefit on this check is the reason it's worth institutionalising. The check takes 15 minutes. A silent failure runs until someone reconciles the platforms against the warehouse. Every week of it means decisions made on bad data, plus the revenue lost while Smart Bidding bids down campaigns that are still working. It's cheap insurance, as long as it's a fixed step in every release that touches tracking.
A clean consent layer comes first in the measurement stack: Enhanced Conversions and CAPI cannot recover signal that was never captured, and the two-layer measurement model assumes the signal layer is intact before MMM cross-checks against it.