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 ✗ Consent required
Advertising / Targeting Facebook Pixel (_fbp), Google Ads (_gcl), TikTok, Bing Ads ✗ Consent required
⚠️
The "functional" grey zone

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.

Scan my site →

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.

🚫
Wrong — GA loads unconditionally

This pattern violates GDPR/ePrivacy because analytics tracking begins before the user has any opportunity to consent or decline.

❌ Bad — fires before consent
<!-- 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>
✅ Correct — only loads after consent signal
<!-- 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.

Express.js — Set Secure + SameSite on all cookies
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:

.github/workflows/cookie-compliance.yml
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.

💡
Tip: Scan staging, not production

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)
Consent Mode v2 — default denied, update on consent
// 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'
});
⚠️
Consent Mode v2 ≠ GDPR consent

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)

1
Audit all cookies that load before user interaction
Run a passive scan (CookieGuard, browser devtools Network tab on cold load, or a curl with cookie capture) to inventory every cookie set before any JS runs.
Critical
2
Gate all analytics cookies behind explicit consent
Google Analytics, Mixpanel, Amplitude, HubSpot — none should load until the user actively accepts analytics cookies. Don't pre-tick the analytics checkbox.
Critical
3
Gate all advertising pixels behind explicit consent
Facebook Pixel, Google Ads, TikTok Pixel, Pinterest Tag, LinkedIn Insight — all require opt-in consent, not just "legitimate interest".
Critical
4
Implement Consent Mode v2 if using Google Ads / GA4
Set default consent to 'denied' for all four parameters. Update to 'granted' only after the user's explicit choice. Required for Google conversion modelling.
High
5
Ensure your consent banner offers a genuine "Reject All" option
The reject option must be as prominent as "Accept All" — same size, same colour, same placement. Hiding the reject button in a nested "Manage preferences" menu is a dark pattern regulators actively target.
High
6
Record and store consent with timestamps
Log which user accepted which categories at what time, using which banner version. You must be able to demonstrate consent in a regulatory audit. Keep consent records for at least 3 years.
High
7
Set Secure + HttpOnly + SameSite on all server-set cookies
Every session or auth cookie should have Secure; HttpOnly; SameSite=Lax. This is both a security requirement and increasingly a compliance signal.
Medium
8
Cap cookie lifetime at 13 months for non-essential cookies
Check all Max-Age and Expires values. Analytics and advertising cookies must not persist longer than 13 months without re-consent.
Medium
9
Update your Privacy Policy / Cookie Policy to reflect all cookies
Every cookie must be documented: name, purpose, provider, retention period. Undisclosed cookies are a direct violation regardless of consent mechanism.
Medium
10
Add a cookie compliance scan to your CI/CD pipeline
New trackers get added constantly — by teammates, by marketing, by third-party SDKs. Automated scanning on every deploy catches regressions before they ship. See CookieGuard GitHub Action docs.
Automation

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.

Start free scan →