How to Check if Your Web Analytics Setup Is GDPR Compliant (Consent Mode for Google, Microsoft & More)

Key Takeaways
  • GDPR compliance requires verifying three distinct consent states: before any choice, after accept, and after reject. Checking your CMP config or GTM container covers none of them.
  • Google Consent Mode v2 embeds consent in two network parameters: GCS (the granted/denied state) and GCD (the full default and update history for all five consent types). Both need to be correct.
  • Microsoft UET Consent Mode uses a single ASC parameter: G for granted, D for denied. If it is missing entirely, UET Consent Mode is not configured.
  • Microsoft Clarity carries no network-level consent signal. You validate it through the JavaScript API, and you must wait for the async stub to settle before reading the value.
  • Manual tools (Google Tag Assistant, UET Tag Helper, DevTools network tab) test one vendor, one state, one session. They will not catch a tag that fires after accept but still carries a denied signal.
  • A live behavioral audit runs a real browser from a German IP, clicks your actual consent banner, and records what every vendor fires and what signal it carries across all three states in one run.

What you are actually trying to verify

Under GDPR and the ePrivacy Directive, any tag that sets cookies or processes personal data may only fire after a user has given informed consent. That covers Google Analytics 4, Google Ads, Microsoft Ads, Microsoft Clarity, Meta Pixel, TikTok, Pinterest, and any other vendor running on your site.

The compliance question is not whether your CMP is configured correctly. It is whether tags actually behave correctly in a live browser session. A cookie banner can look right, your GTM container can look right, and your CMP dashboard can show a good acceptance rate, while tags fire before consent, or fire after accept carrying a denied signal, or keep firing after reject. All three failures are invisible unless you watch the network.

What you need to verify, per vendor, across three consent states:

  • Does the tag fire before the user makes any choice? Most likely, it shouldn’t.
  • Does the tag fire after accept, with a correctly granted consent signal? It must.
  • Does the tag stop firing after reject, or if it is permitted to fire (Google, Microsoft UET), does it carry a correctly denied signal? It must do one or the other.

Everything in this guide is structured around that verification standard.


The page has loaded. The consent banner is visible. The user has not clicked anything. At this point, only your tag manager container (GTM, for example) should be making network requests. No analytics or advertising vendor tag should fire.

If a vendor tag fires here, it is a GDPR violation regardless of what your CMP config says. The tag fired before lawful consent was collected.

In some EU countries, the GTM itself is no longer considered “functional/essential” and you should ask consent before firing it. But this largely depends on how strict your interpretation of the GDPR is.

[Screenshot suggestion: browser DevTools network tab showing only the GTM container request loading, with no GA4, UET, or Meta Pixel requests visible. Annotate the timeline to show this is before any banner interaction.]

After accept

The user clicked your accept button. All enabled vendor tags should now fire, and each should carry a correctly granted consent signal. Tags that fire but still carry a denied signal are a misconfiguration, your CMP’s update call is not reaching the tag correctly. This is one of the most common silent failures in consent mode implementations.

[Screenshot suggestion: DevTools network tab after clicking accept, showing GA4 pageview request with gcs=G111 highlighted in the query string.]

After reject

The user clicked your reject button. Non-essential vendor tags must stop firing entirely. The exceptions, under what is called Normal compliance mode, are Google tags running Advanced Consent Mode (permitted to fire with a denied GCS signal) and Microsoft UET running UET Consent Mode (permitted to fire with a denied ASC signal). All other vendors not carrying consent signals like Meta Pixel, TikTok, Pinterest, must not fire at all after rejection.

[Screenshot suggestion: DevTools network tab after clicking reject showing no Meta or TikTok requests, but a GA4 request with gcs=G100 annotated as permitted under Normal mode.]


The official tool for validating Google tags is Google Tag Assistant, available at tagassistant.google.com. It loads your site in a monitored session and shows you every GA4 and Google Ads request with the consent parameters attached. Or you can test it by looking at the consent state and network request directly in your browser

Using your browser

  1. Before touching the consent banner, open the developer tools and check the network request. Make sure to check the box “preserve log” in the network request tab and refresh the page.
  2. Usually after the refresh, you will get a lot of network requests. Using filters might be helpful to check each vendor. Use collect? for GA4 or googleads for Google Ads, we suggest you start filtering by the name of the vendor and see what comes up.
  3. At this stage, only necessary vendors should fire. e.g. Google Tag Manager. Some GDPR interpretations will suggest that here, nothing should fire, not even Google Tag carrying denied consent signals (GCS:100).
  4. Now accept and verify that all the tags are firing correctly. For the Google events, make sure to check the GCS parameter is sent as GCS111. For Microsoft events, you may want to have a look at ASC:G/D which will be granted or denied respectively. And for Clarity, you should run the code below in the console and look at the results.
clarity('metadata', (d, upgrade, consent) => {
       console.log('consentStatus:', consent);
  }, false, true, true);
// results
{
   analytics_storage: "GRANTED"// OR "DENIED",
   ad_storage: "GRANTED"
};
  1. For other vendors, you may want to singularly look at each one and make sure that they fire correctly
  2. Now repeat from step 3 but rejecting the consent instead. On reject, specifically for Clarity, make sure no cookie is set. clck_ or clsk_ check for these 2 in your application tab in the devtools and after have expanded cookies, click on the domain you’re currently on to see all the cookies. (Or simply type in the console document.cookie)

Using Google Tag Assistant

  1. Go to tagassistant.google.com and enter your domain.
  2. Tag Assistant will open your site in a new window with monitoring active.
  3. Before touching the consent banner, check the tag list on the left. Only GTM should appear as active.
  4. Click your consent banner’s accept button. GA4 and Google Ads tags and any other tag you load through GTM should now appear and fire.
  5. Click on a GA4 pageview event and expand the parameters. Look for the gcs and fields. and for Microsoft look at asc
  6. Repeat from step 3 using your reject button instead, and verify what fires.

[Screenshot suggestion: Google Tag Assistant showing a GA4 pageview event selected, with the parameters panel expanded and gcs=G111 visible. Annotate the gcs field.]

Tag Assistant also shows GTM’s internal consent state, the Default and Update values GTM recorded at the time of each request. This is important because a tag can carry the right network-level signal but still reflect the wrong GTM state if the CMP update call arrived in the wrong order. Look for the Consent tab within a tag’s detail panel to see the per-signal Default and Update values for ad_storage, analytics_storage, ad_user_data, ad_personalization, and ad_data_redaction.

[Screenshot suggestion: Tag Assistant consent tab showing Default and Update values side by side for all five consent types after the accept interaction.]


Decoding the GCS parameter

Every GA4 and Google Ads network request carries two consent parameters you should know how to read.

The GCS parameter

The gcs parameter encodes the granted or denied state at the time of the request:

GCS valueMeaning
G111ad_storage and analytics_storage both granted
G100Both denied, valid under Advanced Consent Mode after reject
G110analytics_storage granted, ad_storage denied
G101ad_storage granted, analytics_storage denied
MissingGoogle Consent Mode not wired correctly to the CMP

A missing gcs parameter after accept does not mean consent mode is absent, it means it is present but broken. Conversion modelling and audience recovery will silently fail even though data appears to flow.

[Screenshot suggestion: a GA4 network request in DevTools with the full query string visible, with gcs and gcd parameters highlighted and a small annotation key mapping the gcd letters to their meanings.]


Checking via browser console

You can inspect the UET consent state directly in the browser console:

// Is UET Consent Mode enabled?
window.uetq.uetConfig.consent.enabled

// Is ad_storage currently granted?
window.uetq.uetConfig.consent.adStorageAllowed

Run these in the DevTools console after the page has loaded and before interacting with the banner, then again after accept and after reject. Also look at the network request to make sure that if something is sent, the right consent signal is associated with it.

  • Before consent: asc should show D (Denied). If UET Consent Mode is not configured, the parameter might be absent entirely.
  • After accept: asc should now show G (Granted).
  • After deny: asc should now show D (Denied).

ASC parameter reference

ASC valueMeaning
Gad_storage granted
Dad_storage denied, valid under UET Consent Mode after reject
MissingUET Consent Mode not configured

Clarity does not embed a consent signal in its network requests. There is no asc or gcs equivalent in Clarity’s outgoing calls. Compliance is validated through the JavaScript API.

Open your browser DevTools and go to the Console tab. Run:

clarity('metadata', (d, upgrade, consent) => {
       console.log('consentStatus:', consent);
  }, false, true, true);
  
  
// Results
{
   analytics_storage: "GRANTED"// OR "DENIED",
   ad_storage: "GRANTED"
};
  

Run this after the page has settled, not immediately on load. Clarity initialises asynchronously.

[Screenshot suggestion: browser DevTools console showing the clarity() call and the resulting consent object printed below it, with analytics_Storage: “denied” visible before consent is given.]


How to check Meta, TikTok, Pinterest and others manually

Some vendors might not have dedicated Consent Signals yet.

What to look for in the network tab

  1. Open DevTools and go to the Network tab. Filter by the relevant domain:
    • Meta Pixel: filter for facebook.net or fbevents.js
    • TikTok: filter for analytics.tiktok.com
    • Pinterest: filter for ct.pinterest.com
  2. Reload the page with the banner visible (use a clean session or incognito).
  3. Confirm that no requests to these domains appear before consent.
  4. Click accept. Requests should now appear.
  5. Reload into a clean session, click reject. No requests from these domains should appear at all.

[Screenshot suggestion: DevTools network tab filtered for facebook.net showing zero requests in the idle state, then the same filter after accept showing the fbevents pageview request.]

These vendors have no equivalent of Advanced Consent Mode or UET Consent Mode. There is no mechanism by which they are permitted to fire with a denied signal. If they fire after reject under any mode, that is a violation.


Where manual checking breaks down

Manual tools are the right starting point. But there are specific failure modes they consistently miss.

You test one vendor at a time. When running DevTools network checks, you need separate sessions where you clear cookies and refresh the page between each state

Config inspection is not behaviour observation. Several CMP checkers inspect your dataLayer or GTM container configuration. They tell you what the consent mode setup looks like statically. They do not tell you what a GA4 request actually carried in its gcs parameter when it fired in a live session.

The most common real-world failure is a tag that carries the wrong consent signals. For example, this means GA4 is recording pageviews but treating them as unconsented. This also degrades your attribution by increasing direct or not-set traffic, and conversion modelling will not be as accurate as you might expect.

A live behavioral audit removes all of these gaps by automating all three states, for all vendors, in a single browser session, and validating every network request against the expected consent signal.


What a live behavioral audit catches

AssertionHub’s free GDPR consent mode audit runs the three-state test automatically in a real browser, from a German server IP, against your actual consent banner, without installation, extensions, or code changes.

What it does that manual tools cannot:

  • Tests all vendors simultaneously in the same session, catching cross-vendor timing issues
  • Validates the gcs parameter on every GA4 and Google Ads request, not just whether the tag fired, but what signal it carried
  • Validates the asc parameter on every UET request
  • Reads Clarity’s consent state from the JavaScript API after the page has settled, not inline with network capture
  • Records the GTM internal consent state (Default and Update values) per signal, per request, per consent state
  • Reports Strict compliance (no vendor fires at all after reject) and Normal compliance (Google and UET permitted with denied signals) separately so you can evaluate both standards

The audit surfaces failures that are invisible to configuration tools and easy to miss in manual testing:

  • Vendor fires before consent with no denied signal, the tag is not waiting for the banner
  • GCS missing after accept, Google Consent Mode is present but not correctly wired to the CMP update call
  • Tag fires after accept but carries a denied signal, the CMP default state is being sent instead of the post-consent update state
  • Clarity fires network requests before consent, the clarity('consent') call is missing or firing too late

[Screenshot suggestion: example audit report showing the three-state summary table with per-vendor pass/fail verdicts and GCS values highlighted for a site with the “fires after accept with denied signal” failure.]


Running the free audit

  1. Open the free GDPR consent mode audit
  2. Enter your website URL
  3. Enter the exact text of your accept button as it appears on the consent banner
  4. Enter the exact text of your reject button
  5. Enter your email address to receive the full report
  6. Submit. No installation, browser extension, or code changes required.

Results arrive in 5–10 minutes. The report covers every detected vendor across all three consent states, with per-vendor verdicts, raw GCS and ASC values, GTM internal consent state (Default and Update) at request time, Microsoft UET consent state, Clarity API consent state, and overall pass or fail for both Strict and Normal compliance modes.

Vendors audited automatically

  • Google Analytics 4
  • Google Ads
  • Google Tag Manager
  • Meta Pixel
  • TikTok Pixel
  • Pinterest Tag
  • Microsoft Ads (UET / Bing)
  • Microsoft Clarity

If your site localises banner text by country, use the text shown to German visitors, the browser runs from a German server


Who should use this

  • Developers implementing or debugging Google Consent Mode v2 or Microsoft UET Consent Mode, use the manual sections to understand what you are targeting, then use the audit to confirm the full stack behaves correctly across all three states
  • Digital marketers verifying a full tracking stack before or after a CMP migration
  • Legal and compliance teams conducting GDPR readiness reviews where a documented, timestamped report is required
  • Agency QA teams running pre-launch consent audits for EU clients across multiple vendors
  • eCommerce brands in the EU running Google Ads, Microsoft Ads, or Meta who need confidence that consent is being respected and that conversion modelling signals are correct

FAQ

Frequently Asked Questions

Is this audit free?
Yes. The GDPR consent mode audit is completely free. No account required.
Does it work with any CMP?
Yes. The audit works with any Consent Management Platform: OneTrust, Cookiebot, CookieYes, Iubenda, Usercentrics, Transcend, Consentmanager, and custom implementations.
What if my banner uses a closed shadow DOM?
Some CMPs including Transcend render their banners inside a closed shadow DOM. AssertionHub handles this automatically and can still interact with accept and reject buttons.
My site shows different button text depending on the visitor's country. What should I enter?
Enter the text your banner shows to visitors in Germany. The audit browser connects from a German server, so your CMP will serve the German-localised version of the banner.
Does it check GDPR compliance directly?
The audit validates the technical implementation: whether tags fire correctly relative to user consent choices, and whether the correct consent signals are present per vendor. It does not provide legal advice. For a full GDPR compliance assessment, consult a qualified privacy lawyer or DPO.
What is Advanced Consent Mode?
Advanced Consent Mode is Google's framework allowing GA4 and Google Ads to send cookieless, anonymised pings even when consent is denied. These pings carry a denied GCS signal such as G100 and are used to model conversions and fill measurement gaps. A site using Advanced Consent Mode correctly will show amber warnings in strict mode but pass normal compliance.
What is Microsoft UET Consent Mode?
Microsoft UET Consent Mode is Microsoft's equivalent framework for Bing Ads. When configured, UET requests carry an ASC parameter: asc=G when consent is granted and asc=D when denied. A denied-signal UET ping is acceptable under normal compliance mode, equivalent to a G100 Google tag ping.
Does it audit Microsoft Clarity?
Yes. Clarity does not carry a network-level consent signal equivalent to GCS or ASC. The audit reads Clarity's consent state through the JavaScript API: clarity('metadata', callback, false, true, true), which returns a consent object with analytics_Storage and ad_Storage fields. If Clarity is firing network requests while that API returns a denied state, the implementation is flagged as non-compliant. The consent state is read after the page has fully settled to avoid reading a transient value from Clarity's async startup sequence.
What can I do if a tag fires after accept but with the wrong consent signal?
This is a CMP-to-GTM wiring issue. Check that your CMP's accept callback is calling gtag('consent', 'update', {...}) with the correct granted values, and that this fires before GTM fires the dependent tags. If you are using a CMP template in GTM, verify the template version supports Consent Mode v2 and that the consent types map correctly to your CMP's categories.
How is this different from a cookie scanner?
A cookie scanner reads the cookies set on a page. This audit validates the actual network requests fired by tracking tags relative to the user's consent decision, including tags that fire before any cookies are set, and the consent signals embedded in those requests. It is a behavioural audit, not a cookie inventory.
Powered by beluacode Logo