What cookies actually require consent?
Under the GDPR and the ePrivacy Directive, the rule is simple: any cookie that isn't strictly necessary to deliver the service the user requested requires explicit consent before it's set.
Think of it in three buckets:
| Cookie Type | Examples | Consent Required? |
|---|---|---|
| Strictly Necessary | Session IDs, CSRF tokens, login state, shopping cart | ✓ No consent needed |
| Functional / Preferences | Language preference, UI settings, dark mode state | ⚠ Debated — often needs consent |
| Analytics | Google Analytics (_ga), Mixpanel, Amplitude, HubSpot |
|
| Advertising / Targeting | Facebook Pixel (_fbp), Google Ads (_gcl), TikTok, Bing Ads |
Cookie banners often categorise preference cookies as "functional" and pre-tick them. Regulators (especially the French CNIL and the Dutch AP) have explicitly rejected this. If a cookie isn't essential for the service to work, treat it as requiring consent.
How to audit your site in 30 seconds
Before fixing anything, you need a baseline. The fastest way is a passive scan — no code changes required.
CookieGuard's free scanner makes an unauthenticated HTTP request to your URL, captures every Set-Cookie header returned before any JavaScript executes, and flags violations against a rules engine covering GDPR, ePrivacy, and the ICO guidance. The scan typically completes in under 5 seconds.
Scan your site now — free, no account needed
See exactly which cookies fire before consent. Takes 30 seconds.
For a deeper audit (JavaScript-executed cookies, third-party iframes), you'll need a headless browser scan. CookieGuard Pro handles this automatically — it loads your page in a real Chromium context, intercepts all network requests, and captures cookies set by client-side code.
The 5 most common violations (and how to fix them)
1. Google Analytics loading before consent
This is the #1 violation we find. The classic pattern: gtag.js or analytics.js is added to the <head> unconditionally. GA fires on page load, sets _ga and _gid, and you've already collected data without consent.
This pattern violates GDPR/ePrivacy because analytics tracking begins before the user has any opportunity to consent or decline.
<!-- In <head> — unconditional load --> <script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX"></script> <script> window.dataLayer = window.dataLayer || []; function gtag(){ dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'G-XXXXXXXX'); </script>
<!-- Load GA ONLY after user consents --> function loadAnalytics() { const script = document.createElement('script'); script.src = 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX'; script.async = true; document.head.appendChild(script); window.dataLayer = window.dataLayer || []; function gtag(){ dataLayer.push(arguments); } gtag('js', new Date()); gtag('config', 'G-XXXXXXXX'); } // Call this only when user clicks "Accept" on your consent banner document.getElementById('accept-btn').addEventListener('click', () => { localStorage.setItem('cookie_consent', 'granted'); loadAnalytics(); });
2. Facebook Pixel set without consent
Same problem, different cookie. The Facebook Pixel sets _fbp on first load regardless of user choice. The Pixel's base code includes fbq('init', 'YOUR_PIXEL_ID') which fires immediately.
Fix: Gate the fbq('init') call behind your consent callback. Do not rely on the "Limited Data Use" flag as a GDPR workaround — that's a US-specific mechanism and does not satisfy European consent requirements.
3. Third-party chat widgets and A/B testing tools
Intercom, Drift, Hotjar, Optimizely — every one of these sets tracking cookies on load. A common mistake is to gate Google Analytics but forget the chat widget, which happily sets its own identifiers without asking.
Run a full audit and list every third-party script. Each one that isn't strictly necessary needs to be gated behind consent.
4. Cookies without the Secure flag on HTTPS sites
Less of a GDPR issue, more of a security one — but regulators increasingly consider data security as part of overall compliance. Any cookie on an HTTPS site that lacks the Secure flag can theoretically be transmitted over HTTP, exposing it to interception.
res.cookie('session_id', token, { httpOnly: true, secure: process.env.NODE_ENV === 'production', sameSite: 'lax', maxAge: 7 * 24 * 60 * 60 * 1000 // 7 days in ms });
5. Cookies with lifetime > 13 months
The ePrivacy Directive and the French CNIL specifically flag cookies with retention periods beyond 13 months as problematic. Google's own guidelines for Consent Mode v2 cap advertising cookies at 13 months. Check your Max-Age and Expires values.
The CI/CD approach: scan on every deploy
Manual audits go stale. A developer adds a new marketing pixel in week 3, and by month 6 you're non-compliant again. The sustainable fix is to run a compliance scan in your CI pipeline on every deploy — and fail the deploy if new tracking cookies appear without consent gates.
CookieGuard provides a GitHub Action that does exactly this:
name: Cookie Compliance Check on: push: branches: [ main, staging ] pull_request: branches: [ main ] jobs: cookie-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run CookieGuard Scan uses: cookieguard/scan-action@v1 with: url: ${{ secrets.STAGING_URL }} api-key: ${{ secrets.COOKIEGUARD_API_KEY }} fail-on-violations: critical,high
The action calls the CookieGuard API, runs the compliance scan against your deployed URL, and marks the check as failed if any critical or high-severity violations are found. Pull requests that introduce new unconsented tracking cookies won't merge.
Point the action at your staging URL (deployed from the same PR branch) so violations are caught before they ever hit users. See the full API docs for configuration options.
Consent Mode v2 — Google's 2024 mandate (still in effect)
Since March 2024, Google requires all websites using Google Ads or Google Analytics to implement Consent Mode v2 for users in the European Economic Area. As of 2026, non-compliant sites lose remarketing capabilities and conversion modelling.
Consent Mode v2 requires you to signal two additional consent states to Google's tag infrastructure:
| Consent Parameter | Controls | Default if Not Set |
|---|---|---|
ad_user_data |
Whether user data can be sent to Google for ads purposes | Denied (safe) |
ad_personalization |
Whether personalised advertising is enabled | Denied (safe) |
analytics_storage |
Whether analytics cookies can be stored | Denied (safe) |
ad_storage |
Whether advertising cookies can be stored | Denied (safe) |
// Set defaults before GTM loads (in <head>, before gtag.js) window.dataLayer = window.dataLayer || []; function gtag(){ dataLayer.push(arguments); } gtag('consent', 'default', { ad_storage: 'denied', ad_user_data: 'denied', ad_personalization: 'denied', analytics_storage: 'denied', wait_for_update: 500 }); // After user grants consent: gtag('consent', 'update', { ad_storage: 'granted', ad_user_data: 'granted', ad_personalization: 'granted', analytics_storage: 'granted' });
Implementing Consent Mode v2 tells Google how to behave, but it doesn't replace your obligation to obtain valid GDPR consent. You still need a compliant consent banner that records user choices and fires gtag('consent', 'update', ...) based on the user's actual decision — not a blanket 'granted' on page load.
The 10-point compliance checklist
Use this before launch, after major changes, and after any third-party script is added.
Cookie Compliance Checklist (2026)
Secure; HttpOnly; SameSite=Lax. This is both a security requirement and increasingly a compliance signal.Max-Age and Expires values. Analytics and advertising cookies must not persist longer than 13 months without re-consent.Quick wins vs. the long game
If you're starting from zero, prioritise in this order:
Day 1: Run a free scan. Identify what's firing. Gate the biggest offenders (GA, Facebook Pixel) behind consent. This alone eliminates 80% of your risk exposure.
Week 1: Implement Consent Mode v2. Add a proper reject path to your banner. Document your cookies in your Privacy Policy.
Month 1: Add the CI/CD scan. Set up consent logging. Review all third-party widgets.
For a deeper comparison of how CookieGuard stacks up against the major consent management platforms, see our comparison pages: CookieGuard vs Cookiebot and CookieGuard vs OneTrust.
Scan your site free → cookieguard.sh
No account required. Instant compliance report. Takes 30 seconds.