Cookies Set Before Consent: The Most Common GDPR Failure
Here's a failure mode that shows up on a lot of sites that think they're fine. The banner is there. It has a reject button. The wording is good. And the analytics cookie was already written before the banner finished rendering.
That gap between having a consent mechanism and having consent is the finding we hit most often on sites that have genuinely tried.
Why prior consent is the requirement
Article 5(3) of the ePrivacy Directive requires consent before storage or access to information on a user's device. Not at the same time. Not shortly afterwards.
Deleting the cookie later doesn't cure it. If you drop it and then remove it when the user declines, the storage still happened without a legal basis. "We anonymise it later" doesn't help either, because the regulated act is writing to the device, not what you do with the data afterwards.
The reason this is so easy to miss: nothing about it is visible to a user, and nothing in your banner configuration reports it. The banner is doing its job perfectly. The problem is everything running alongside it.
For the full picture on consent requirements, see our GDPR cookie consent guide.
How to check your own site in two minutes
Open a private window, load your homepage, and don't touch the banner. Then open developer tools.
Under Application, look at Cookies and Local Storage. Under Network, filter by third-party domains.
Anything beyond your own session cookie means you have a prior-consent problem: an analytics identifier, an advertising pixel, a video embed's tracking cookie.
Three things to get right while you do this. Use a private window, or an existing consent cookie will suppress the banner and hide the issue entirely. Check more than the homepage, because landing pages and blog posts often carry embeds the homepage doesn't. And check a mobile viewport, since some tag configurations differ.
The usual culprits
Tag managers that initialise on load. The container itself is usually harmless, but tags inside it fire on page view unless you explicitly gate them. This is the single biggest cause we see: the consent tool and the tag manager are both installed correctly, and nobody wired them together.
Analytics with automatic initialisation. Most analytics snippets are built to start immediately. Wrong default for the EU.
Third-party embeds. YouTube players, social posts, comment widgets, live chat, maps. They set cookies the moment the iframe loads, and they get forgotten because nobody thinks of them as tracking.
Fonts and CDNs that leak data. Loading fonts from a third-party origin sends the visitor's IP address to that provider. German courts have already dealt with this. Self-hosting removes it entirely.
A/B testing and personalisation tools. These need to run early to avoid content flicker, which creates real pressure to load them before consent. The pressure is understandable. It doesn't change the legal position.
Server-set cookies. Easy to miss, because they never show up in your JavaScript. If your framework or CDN sets an analytics or affinity cookie at the edge, that's still storage on the user's device.
Fixing it
Block by default, unblock on consent. Nothing non-essential should load until a signal says it may. In practice, tag scripts get a placeholder type so the browser won't execute them, and the consent handler rewrites them:
<script type="text/plain" data-consent="analytics" src="/analytics.js"></script>
// On consent for the analytics category, activate the tagged scripts.
function activate(category) {
document
.querySelectorAll(`script[type="text/plain"][data-consent="${category}"]`)
.forEach((node) => {
const script = document.createElement('script')
for (const { name, value } of node.attributes) {
if (name !== 'type' && name !== 'data-consent') {
script.setAttribute(name, value)
}
}
script.type = 'text/javascript'
node.replaceWith(script)
})
}
Gate the tag manager itself, not the tags inside it. Trigger the container on a consent event instead of on page view. One change instead of one per tag, and new tags inherit the gate for free.
Facade your embeds. Swap the third-party iframe for a static preview image that loads the real embed on click. Users who never click never contact the third party, and your page gets faster.
Self-host fonts and static assets. Kills an entire category of the problem for very little work.
Re-test after every change to marketing tooling. This is the part teams skip. Prior-consent compliance isn't a state you reach once. It degrades the moment someone adds a tag, which is why it belongs in your deployment checks and not an annual audit.
What "strictly necessary" actually covers
The fix depends on classification, so be precise here.
Exempt: session and authentication cookies, shopping baskets, load balancing, CSRF tokens, and the cookie recording the user's consent choice.
Not exempt: analytics of any kind, including first-party and self-hosted. A/B testing. Heatmaps and session recording. Advertising and retargeting. Social embeds.
The test is whether the service the user explicitly requested would break without it. Not whether it's useful to you.
What to do about it
Prior consent is where good-faith implementations break, because the banner and the tracking are usually configured by different people at different times and nothing surfaces the gap.
Two minutes in a private window with devtools open tells you where you stand. If anything writes to the device before you click, the fix is architectural: block by default, activate on signal, re-test whenever the marketing stack changes.
This article is general information, not legal advice.
Sources: ePrivacy Directive, Article 5(3) · EDPB: Report of the cookie banner taskforce