Skip to content
Consent ModeGDPRCMPCompliance

Your CMP Might Accept 'Reject All' and Still Track Users. Here's How to Test.

·6 min read

Every consent audit we've ever seen a client run tests the same thing: click Accept all, check that GA4 starts firing, confirm gcs=G111 appears on the network, ship it. The CMP works.

But "Accept all" is not where CMPs fail. Clicking accept grants everything — there's no mismatch possible. The failure mode every regulator cares about is the other button: the one the compliance team hopes nobody clicks.

The failure mode nobody tests

When a user clicks Reject all, three things should happen:

  1. All four Consent Mode v2 signals (ad_storage, analytics_storage, ad_user_data, ad_personalization) transition or remain at denied.
  2. Any tracking tag gated by consent stops firing — no new GA4 requests should hit /g/collect with a granted gcs.
  3. The user's choice persists across navigation and future visits (usually via an opt-out cookie or localStorage flag).

In the field, step 1 fails routinely. We've seen CMPs that:

Why this is a direct GDPR violation

A user who clicks "Reject all" has expressed an explicit, informed refusal of consent under the ePrivacy Directive. If tracking continues after that click, every subsequent data point is collected without a lawful basis. Under GDPR, the fine ceiling is 4% of global annual turnover. Under France's CNIL enforcement priorities (similar regulators exist across EU member states), this is exactly the scenario that triggered the largest consent fines of 2023-2024.

It's also the scenario least likely to be caught during a standard compliance review — because everybody tests accept and nobody tests reject.

How to test it in your browser

The manual test is straightforward but tedious, which is why it's skipped:

  1. Open a private/incognito window.
  2. Open DevTools → Network, filter by collect.
  3. Navigate to the site.
  4. Wait for the cookie banner.
  5. Click Reject all.
  6. In the console, paste:
    Object.fromEntries(
      Object.entries(google_tag_data.ics.entries).map(
        ([k, v]) => [k, v.default ? 'granted' : 'denied']
      )
    )
  7. Every value should be denied. Any granted is a finding.
  8. Navigate to another page on the site. Watch Network. No new GA4 requests should fire with a granted gcs.

If you manage a portfolio of client sites, running this across all of them is hours of work. Which is why it doesn't get done.

How our audit automates it

Check My Tracking's audit engine runs the reject-flow test automatically as part of its CP_03 check. Under the hood it:

  1. Runs the primary scan (navigate, accept CMP, verify accept behavior) — this is what every audit does.
  2. Launches a second isolated browser context from a clean state.
  3. Navigates to the same URL, waits for the CMP, looks up the correct reject selector in our registry (we maintain stable selectors for Cookiebot, OneTrust, CookieYes, Didomi, Iubenda, Usercentrics v3, Klaro, Borlabs, Complianz, Osano, and consentmanager).
  4. Clicks reject, waits 1.5 seconds for the CMP to propagate the choice to Consent Mode.
  5. Reads google_tag_data.ics.entries and captures any GA4 request that fires after the click.
  6. If ad_storage or analytics_storage is still granted after reject, CP_03 fails regardless of how the accept path went.

The accept-path still matters (a broken accept is a product issue — no attribution). But the reject-path is the regulatory risk. Testing both is the only way to know your CMP actually does what you paid it for.

What to do if your reject test fails

If our audit surfaces a reject-flow failure on your site, the fix depends on where the break is:

Reject is the test that matters

Reject-all validation is the single highest-leverage consent compliance check you can run — precisely because nobody else is running it. Manual testing is tedious, automated audit tools don't bother. If your site passes our free scan's CP_03 reject-flow check, you're ahead of roughly 70% of production consent implementations we've seen.