Skip to content

Research

80% of Cookie Reject Buttons Don't Actually Work — Here's the Proof

GDPR Privacy Monitor Research · 2026-04-11 · 6 min read

Every cookie banner makes the same implicit promise: click "Reject" and the tracking stops. The banner disappears, and you browse in peace. That is the bargain the consent model is built on -- the idea that users have a meaningful, enforceable choice.

We tested that promise on 28,891 EU websites. On 80.4% of them, the promise is broken. Tracking continues after the user explicitly clicks reject. Cookies persist. Advertising pixels keep firing. And on 1,642 sites, cookies that the reject action initially clears come back the next time the page loads -- a pattern we call consent respawn.

This is not a marginal finding about a few misconfigured sites. It points to a systemic issue in the mechanism that hundreds of millions of EU residents rely on for their privacy rights.

What "Reject" Is Supposed to Do -- Legally

The legal framework is clear. Under Article 5(3) of the ePrivacy Directive, storing or accessing information on a user's terminal equipment requires prior consent, with a narrow exception for cookies strictly necessary for a service the user has explicitly requested. GDPR Article 7(3) adds that withdrawing consent must be as easy as giving it, and the data controller must act on that withdrawal.

The EDPB's Guidelines 05/2020 on consent under GDPR spell out what this means for reject buttons: if a website offers an "Accept All" option, it must also offer an equally prominent and equally accessible option to refuse. And that refusal must be effective -- it must actually prevent the processing that consent would have authorized.

The CJEU reinforced this in Planet49 (C-673/17): consent requires a clear affirmative act, and pre-ticked checkboxes do not constitute valid consent. The logical corollary is that a refusal -- an explicit negative act -- must be respected as definitively as an acceptance. If clicking "Accept" turns tracking on, clicking "Reject" must turn it off. Not partially. Not temporarily. Completely and persistently.

That is what the law says. Our data shows what actually happens.

How We Test the Reject Flow

Our reject-flow test is designed to be as close as possible to the experience of a real human user clicking reject, with the addition of comprehensive instrumentation. Here is the process step by step:

Step 1: Fresh browser session. The scanner launches a clean Chromium instance -- no cookies, no local storage, no cached resources, no browsing history. This is a genuine first-time visitor with no prior consent state. Step 2: Navigate and record pre-consent state. The scanner loads the target URL and waits for the page to stabilize. Before any interaction, it records every cookie present in the browser, every network request made, and every third-party domain contacted. This is the pre-consent baseline -- what the site does before the user has any opportunity to make a choice. Step 3: Detect the consent banner. Using our detection library covering 45 known CMPs and generic heuristics, the scanner identifies the consent mechanism and locates the reject button. This step uses a layered approach: first checking for known CMP script signatures and their associated DOM structures, then falling back to generic detection of fixed-position elements with consent-related text and button labels like "Reject All," "Decline," "Refuse," or equivalent translations. Step 4: Click reject. The scanner clicks the reject button and waits for the page to settle. "Settle" means waiting for pending network requests to complete, DOM mutations to stop, and any animations or transitions to finish. We use generous timeouts to avoid false positives from slow CMP implementations. Step 5: Post-reject snapshot. The scanner records the complete state again: all cookies, all network activity, all third-party domains. This snapshot is compared against the pre-consent baseline to determine what changed. Step 6: Reload and check for respawn. The scanner reloads the page and waits for it to stabilize again. It then takes a final snapshot. This step is critical: it reveals whether the reject action is persistent (respected across page loads) or whether cookies and tracking re-activate when the page loads fresh. If cookies that were removed in Step 5 reappear in Step 6, that is consent respawn.

Every step produces timestamped, archival evidence: full cookie inventories with names, values, domains, expiry dates, and flags; complete network request logs with URLs, methods, response codes, and timing; and full-page screenshots. This evidence chain allows any individual finding to be verified and challenged.

The Results: 80.4% Failure

Of the 28,891 websites where we successfully completed the full reject-flow test:

  • 5,650 (19.6%) passed. After clicking reject, non-essential cookies were removed, tracking requests stopped, and the rejection persisted across page reloads.
  • 23,241 (80.4%) failed. Tracking continued in some form after the user explicitly clicked reject.

The failures are not uniform. They fall into distinct categories that overlap -- a single site can exhibit multiple failure modes simultaneously.

Persistent cookies: 10,848 sites

On 10,848 sites (37.5% of those tested), non-essential cookies remained in the browser after the reject flow completed. These are cookies classified as analytics, marketing, or tracking-related that should have been removed or prevented from being set after a reject action.

The most common persistent cookies belong to Google Analytics (`_ga`, `_gid`, `_gat`), Meta/Facebook (`_fbp`, `fr`), and various advertising platforms. In many cases, the CMP successfully removes some cookies but fails to catch all of them -- suggesting incomplete integration between the consent management platform and the site's full roster of third-party scripts.

The presence of these cookies after reject is not merely an aesthetic problem. Each one is a persistent identifier that ties the user's current session to past and future visits. The `_ga` cookie, for instance, is a unique client identifier that Google Analytics uses to build a longitudinal profile of the user's behavior across sessions. If it persists after reject, the user's browsing continues to be tracked and aggregated regardless of their expressed refusal.

Persistent trackers: 14,547 sites

On 14,547 sites (50.3% of those tested), tracking services remained active after reject -- meaning the browser continued making requests to known tracking domains even after the user clicked the reject button.

This is a distinct failure mode from cookie persistence. A tracker can be active without setting a cookie: pixel requests, beacon calls, and script loads all transmit information (at minimum, the user's IP address, the referring page, and timing data) to third-party servers regardless of whether a cookie is stored. This is sometimes called "cookieless tracking" and is increasingly common as browsers tighten restrictions on third-party cookies.

The gap between the cookie figure (10,848) and the tracker figure (14,547) is significant. It means that on roughly 3,700 sites, the reject action successfully cleared cookies but failed to prevent tracking requests from continuing. The CMP handled cookie cleanup but did not block the scripts that generate tracking traffic in the first place. This points to a common architectural problem: the CMP is configured to manage cookies (delete them on reject, prevent them on load) but not to manage script execution.

Consent respawn: 1,642 sites, 4,932 cookies

Consent respawn is the most troubling pattern we identified. On 1,642 websites, cookies that were successfully removed by the reject action reappeared after the page was reloaded. Across those sites, 4,932 individual cookies exhibited this respawn behavior.

Consent respawn is not a bug in one CMP or one configuration. It is a structural problem in how consent is implemented across the web stack.

How a cookie comes back after deletion. When a user clicks reject, a properly configured CMP does two things: it deletes existing non-essential cookies (by setting their expiry to a past date), and it updates a consent record (usually a cookie itself, or a localStorage entry) that tells the CMP's blocking logic to prevent non-essential scripts from running on future page loads. If both of these work, the user is clean: no tracking cookies, no tracking scripts.

Consent respawn happens when the deletion succeeds but the blocking fails. The most common scenario:

1. The CMP deletes the `_ga` cookie when the user clicks reject.

2. The CMP sets a consent-state cookie recording that the user has refused analytics.

3. On the next page load, the CMP checks its consent state and knows the user refused.

4. But: the Google Analytics script tag is embedded directly in the page template (outside the tag manager) or is loaded by a tag manager rule that does not check consent state.

5. The GA script loads, sees no `_ga` cookie, and creates a new one.

6. The user's reject decision has been overridden.

Variations on this pattern include: third-party scripts loaded via hardcoded `