Introduction
GDPR compliance scanners assess cookie banners against observable technical behavior, not just their visual presence. A banner can look professional and still fail every scanner check if the underlying consent plumbing is broken. This guide documents the most common cookie banner findings that scanners flag—what they look like, why they occur, and how to fix each one.
The issues covered here are drawn from real scan findings across hundreds of websites. They occur across all CMS platforms and CMP tools, which means the problem is rarely the banner plugin itself—it is usually how the banner was configured, where in the page it initializes, and whether blocking logic is actually connected to consent state.
If your site recently received scanner findings related to its cookie banner, this guide walks through each failure mode with specific diagnostic steps and remediation actions. Scan your site first to get your specific findings as a reference point.
Scanner Findings: What Gets Flagged and Why
Scanners evaluate cookie banners along several dimensions simultaneously. Understanding what each flag means is the first step toward fixing it:
- Pre-consent analytics or ad requests: the scanner loads the page as a new visitor (clean browser state, no cookies) and captures all network requests before any user interaction with the banner. If requests to analytics domains (google-analytics.com, googletagmanager.com, analytics.tiktok.com) or advertising domains (facebook.com/tr, doubleclick.net, googlesyndication.com) appear before the banner is dismissed, this is flagged as a pre-consent tracking failure. This is the most impactful banner finding because it demonstrates that the banner provides no actual protection—trackers run regardless of what the user does.
- No reject option on first banner layer: the scanner checks the initial banner HTML for markers of a rejection pathway. When only an Accept or Continue button is present—with rejection hidden behind a secondary panel—the banner fails the equal-prominence test. This finding does not mean the site has no preferences panel; it means the panel is not reachable in one step from the banner's primary layer.
- Banner not detected: the scanner may not find any banner at all. Common causes include: the banner loads asynchronously and the scanner captures the initial page state before JavaScript executes; the banner is geo-targeted and does not display to the scanner's IP address; the banner was removed during a site migration; a consent cookie from a previous session is being sent with the scanner's request (less common in well-configured scanners that reset state).
- Consent state not persisted: after a user makes a choice, the decision should persist for a defined period so the banner does not recur on every page. Scanners sometimes test persistence by simulating a second visit after consent. If the banner reappears immediately, consent state is not being stored or is being cleared between navigations. This can indicate a misconfigured cookie expiry, a storage conflict, or a CMP initialization error.
- Banner recurrence after consent: distinct from non-persistence. Some banner implementations show the banner on every page regardless of stored consent because the consent check occurs after the banner render, or because the banner initialization code is duplicated in multiple page templates and one instance lacks the consent check. Scanners flag this because it implies users cannot rely on their stored preference being honored.
- Cookie policy link absent from banner: many CMP frameworks require a link to the cookie policy within the banner itself, not only in the site footer. This supports the informed consent requirement—users should be able to read what they are consenting to before they accept. Scanners check for a policy link in the banner HTML.
Root Causes of Banner Failures
Each scanner finding has an underlying technical cause. Diagnosing the cause correctly prevents applying a superficial fix that leaves the actual problem in place:
Cause 1 — CMP loads after GTM
The CMP script initializes after GTM: when Google Tag Manager's container snippet appears in <head> before the CMP JavaScript, GTM's triggers fire before the CMP has had a chance to read or set a consent state. All tags with 'All Pages' or 'Window Loaded' triggers execute immediately. Moving the CMP to load synchronously before GTM, and configuring GTM tags to wait for consent signals, resolves this ordering issue.
Cause 2 — CMP set to notify only, not blocking
The CMP operates in 'notify' mode rather than 'blocking' mode: many consent plugins ship with a default mode that displays a banner and records consent but does not block any third-party scripts. Blocking mode requires an explicit configuration step—enabling it in the plugin settings and mapping each script category to the appropriate consent bucket. Sites that skipped this configuration step have a functional-looking banner with no enforcement behind it.
Cause 3 — Banner template lacks reject button
Banner template does not include a first-layer reject option: some older CMP templates and default theme banner implementations pre-date regulatory guidance on equal-prominence rejection. The template shows Accept and Settings but no Reject. Changing this requires either updating the template (if the CMP supports it in settings) or replacing the banner with a modern implementation.
Cause 4 — Consent cookie misconfigured
Consent cookie has no domain, path, or expiry configured: if the consent storage cookie is set without an explicit domain, it may apply only to the specific subdomain that set it. If set without a path, it may not propagate to subpages. If set with session expiry, it is cleared when the browser tab is closed. All three cause banner recurrence. Check the consent cookie in your browser's Application tab after accepting—it should have your root domain, path /, and an expiry of at least 6–12 months.
Cause 5 — SPA framework banner re-renders on every route
Banner initialized in a component that renders on every page without a pre-render consent check: in React/Next.js, Vue, or other SPA frameworks, if the banner component mounts on every route change without first checking localStorage or cookie state, it will re-render the banner even when consent was stored. The banner component must check consent state before rendering and conditionally skip initialization when a valid consent record exists.
Step-by-Step Fixes for Each Finding
Work through these fixes in order—pre-consent tracking first, then banner UI, then persistence issues. Each fix builds on or validates the previous one.
- Fix script loading order: open your page source or theme template. Find the GTM snippet—it starts with <!-- Google Tag Manager --> and includes a <script> block. Find your CMP script. Ensure the CMP script appears before the GTM snippet in <head>. Both should be in the <head> element, not at the end of <body>. For WordPress sites, check that the CMP plugin's output priority is set lower (higher priority) than the GTM plugin's output priority in the plugin settings.
- Enable blocking mode in your CMP: log into your CMP or consent plugin dashboard. Look for settings labeled 'Auto-blocking', 'Script blocking', 'Cookie blocking', or 'Tag manager integration'. Enable the setting. If the plugin requires you to categorize scripts, assign each third-party script URL or GTM tag to a consent category (analytics, marketing, etc.). Save and publish. Verify by loading your site in a private browser window and checking the Network tab before accepting cookies.
- Add Reject all to the first banner layer: in your CMP's banner builder or template settings, enable the Reject all button. If your CMP does not support this natively, look for a 'Button configuration' or 'First layer buttons' option. The Reject all button should appear alongside Accept all with equivalent visual weight—same button style, same size, adjacent placement. Publish the change.
- Add cookie policy link to banner: in the banner configuration, add a link to your cookie policy URL (typically /cookie-policy or /privacy#cookies). The link should appear within the banner's main text or in a footer area of the banner dialog. Label it 'Cookie policy' or 'Read more about cookies.' This link is often a required field in CMP templates—look for 'Privacy Policy URL' or 'Cookie Policy URL' fields in banner settings.
- Fix consent cookie configuration: check your CMP settings for cookie expiry configuration. Set expiry to at least 180 days (some jurisdictions and DPA guidance recommends 6 months to 1 year). Ensure the cookie domain is set to your root domain (example.com, not www.example.com) so consent persists across subdomains. Set path to /. After saving, clear your browser cookies, accept the banner, then check Application > Cookies in DevTools to verify the consent cookie attributes.
- Fix SPA banner re-rendering: if your site is built with a JavaScript framework, the banner component should check consent state synchronously before rendering. On component mount, read from localStorage or the consent cookie. If a valid, unexpired consent record exists, do not render the banner. Defer banner rendering until after client hydration completes to avoid hydration mismatches on server-rendered pages.
- Verify GTM consent mode integration: if you use GTM, each analytics and advertising tag should be configured to fire only when the relevant consent signal is granted. For GA4, set the trigger to fire when consent_analytics_storage equals 'granted'. For advertising tags, set triggers to require consent_ad_storage and consent_ad_personalization. Test by opening GTM's Preview mode, loading your site, accepting cookies, and confirming tags fire only after acceptance. Reject cookies and confirm tags do not fire.
Verifying the Fixes Work
After applying fixes, verify each change before rescanning. A manual verification takes 10–15 minutes and catches obvious errors before spending a scan on a configuration that is still broken.
- Private browser test — pre-consent check: open a new private/incognito window. Open DevTools (F12) and navigate to the Network tab. Load your site homepage. Before interacting with the banner, check the network requests list. You should see requests to your own domain, CDN, fonts, and images. You should not see requests to google-analytics.com, googletagmanager.com/gtag, facebook.com/tr, doubleclick.net, or other ad/analytics endpoints.
- Private browser test — post-consent check: with the same private window still open, click Accept all on the banner. Check the Network tab again. Analytics and marketing tags should now fire. This confirms that blocking is active and that consent triggers the tags correctly.
- Private browser test — reject flow: close the private window, open a new one, load your site, and click Reject all. Check the Network tab. Analytics and marketing tags should not fire. Navigate to a second page on your site. The banner should not reappear (consent was stored as rejected).
- Cookie inspection: after accepting consent in a private window, open DevTools > Application > Cookies > your domain. Look for your CMP's consent cookie. Verify it has: domain set to root domain, path /, expiry at least 6 months in the future, and that the value encodes your acceptance preferences. Repeat after rejection and verify the value encodes rejection.
- Mobile test: load your site on a mobile device or in DevTools mobile emulation. Verify the banner is visible and both Accept all and Reject all buttons are tappable without horizontal scrolling. Banner accessibility on mobile is a separate area where many implementations fail.
- Rescan: run a GDPRChecker scan on your live domain. Compare the new report against the baseline findings. Banner-related score components should improve. If pre-consent tracking still appears in the report despite your local testing showing no requests, check whether a CDN or edge caching layer is serving a cached HTML page with the old tracking configuration—a cache purge may be required.
Caching: the gap between local and scanner results
A finding that scanner results show pre-consent tracking while your local private browser test shows clean results is almost always a caching issue. Your CDN (Cloudflare, Fastly, AWS CloudFront) may be serving a cached page built before your CMP changes were applied. Purge the cache for your homepage and key landing pages after any CMP configuration change.