The consent gate is in place, no vendor script appears in the Network panel before the banner is answered, and the Application panel still shows third-party cookies on a first visit.

Triage: Identify Which Source Wrote Them

Cookies can appear from four distinct places, and only one of them is the tag you gated. Establish which before changing anything.

  1. Open a fresh incognito window with Application → Cookies visible, and load the page without touching the banner.
  2. Record each cookie’s Domain and Set time. A cookie on your own domain was written by first-party code or by a tag manager; one on a vendor domain came from a request to that vendor.
  3. Switch to Network, filter by Set-Cookie in the response headers, and identify which response carried each cookie.
  4. Check whether the container itself wrote any: tag managers commonly set their own first-party cookies for session and container versioning.
Four sources, one symptom Cookies present before consent can come from four sources. The container itself sets first-party cookies for its own session and version tracking. A tag that was not gated fires and its vendor sets a cookie. A server response includes a Set-Cookie header entirely outside the tag manager. And a vendor loaded by another vendor sets one, which no gate on your side ever saw. the container itself first-party, session and version — usually strictly necessary an ungated tag vendor domain, set by a script request you did not gate a Set-Cookie response header no script involved — outside the tag manager entirely a vendor loaded by a vendor your gate never saw the request that set it Only the second is fixed by the gate. The others need different interventions.

Root Cause: The Gate Covers Tags, Not Everything Tags Do

A consent gate in a tag manager controls whether a tag fires. It does not control what a tag does once it has fired, it does not control the container’s own behaviour, and it has no visibility into responses your server generates or into vendors that other vendors load.

The most common genuine gap is the fourth source. A tag you correctly gated may itself be a loader: it fires after consent, and it then requests a second vendor whose cookies you never accounted for because that vendor does not appear anywhere in your configuration. This is the chained loading problem wearing a compliance hat, and the only reliable way to find it is to observe traffic rather than to read configuration — which is what the script inventory exists for.

The container’s own cookies are usually defensible as strictly necessary, but “usually” is doing work there. A container cookie that records only a session identifier for the container’s own operation is one thing; one that carries a cross-site identifier is another, and the distinction is in the vendor’s documentation rather than in your configuration.

What the gate can and cannot reach The consent gate sits between the container and the tags it controls, so it governs whether each configured tag fires. Outside that boundary are the container own cookies, anything a fired tag subsequently loads, and any Set-Cookie header from your own responses. A note records that the second of those is the gap most often found in an audit. inside the gate configured tags fire only after consent this part usually works outside — container its own cookies review the necessity claim often defensible outside — downstream vendors loaded by vendors invisible in your config the usual audit finding Configuration shows you the first column. Only observed traffic shows you the third.

Resolution: Close Each Source Separately

For ungated tags, set the container’s built-in consent requirements per tag rather than relying on a trigger condition. Consent settings hold the tag in the container’s own queue and release it on a consent update; a trigger condition is evaluated once and can be raced.

For downstream vendors, the fix is upstream: gate the loader more strictly, or replace it. Where the vendor genuinely requires a chained load, the vendor’s own consent configuration has to be set — most major SDKs expose one, and it is a different setting from your container’s.

For server-set cookies, the fix is in your own code, not the tag manager. Emit them conditionally on the resolved policy, exactly as the edge routing resolves everything else.

For container cookies, decide deliberately whether each is strictly necessary, document the reasoning, and disable those that are not.

// A first-party cookie written from your own code, gated properly.
function setPreferenceCookie(value, consent) {
  // Strictly necessary cookies are exempt; everything else waits.
  if (consent.functional !== 'granted') return;
  document.cookie = `pref=${encodeURIComponent(value)}; Path=/; SameSite=Lax; Secure; Max-Age=31536000`;
}

Verification: A Clean First Visit

Open a fresh incognito window, load the page, wait ten seconds, and read the cookie list without touching the banner. Only cookies you have documented as strictly necessary should be present. Repeat after accepting, and after declining — the declined state should look identical to the untouched one.

Three states that must be distinguishable Three checks on the cookie list. Before any interaction, only documented strictly-necessary cookies should be present. After declining, the list should be identical to the untouched state. After accepting, the vendor cookies should appear. A note records that the declined state matching the untouched state is the check that catches a gate which only delays rather than prevents. untouched necessary cookies only each one documented declined identical to untouched nothing added at all accepted vendor cookies appear the gate released them The middle column is the real test: a gate that merely delays will differ from the first.

The audit above produces a list, and the list is worth keeping rather than discarding once the immediate problem is fixed. A cookie register — every cookie the site can set, with its source, its purpose, its lifetime and its classification — is the artefact that turns this from a recurring investigation into a check.

It is also, in most jurisdictions, something you are already obliged to publish in some form. A cookie notice that lists names and purposes is only accurate if it is derived from observation rather than from memory, and deriving it from the same register that engineering uses keeps the public statement and the technical reality from drifting apart.

Generate it the same way as the script inventory: collect from real sessions across the three consent states, diff against a committed baseline, and alert when a new name appears. A cookie you have never seen before is exactly as interesting as a vendor origin you have never seen before, and for the same reason — something is running that nobody added deliberately.

Common Pitfalls

  • Using a trigger condition instead of consent settings. A trigger is evaluated at a moment; consent settings hold the tag until the state changes. Only the second survives a consent decision that arrives late.
  • Auditing with a stored decision present. A returning visitor’s session hides every pre-consent problem. Always audit in a fresh incognito window.
  • Assuming the container own cookies are exempt. Some are; some carry identifiers that are not. Read the vendor’s documentation rather than inferring from the fact that the container sets them.
  • Stopping when the Network panel is clean. A Set-Cookie response header sets a cookie without any script and without a request you would recognise as a vendor call. Check the Application panel, not only the Network panel.

Frequently Asked Questions

Are analytics cookies ever strictly necessary?

Almost never under the usual reading. The exemption covers what is required to deliver a service the user requested — session state, load balancing, security tokens — and measurement of how the service is used is not that, however useful it is to you. Classifying analytics as necessary to avoid gating it is the single most common way an otherwise careful implementation fails a review.

Where the measurement genuinely is aggregate and first-party, there are narrower arguments available in some jurisdictions, and they are worth making explicitly with counsel rather than by relabelling a category. Record the reasoning next to the classification in your inventory so it is a documented position rather than an assumption.

What about cookies set by a tag we cannot configure?

Then the gate has to move up a level: prevent the tag from firing rather than trying to change what it does. If the vendor offers no consent configuration and the tag writes identifiers on load, the only compliant options are to hold the tag entirely until consent or to stop using it.

This situation is worth escalating rather than engineering around. A vendor that cannot be operated compliantly is a procurement problem, and it is one that gets solved much faster when the alternative is removal than when engineering keeps finding workarounds.

Does blocking cookies stop the vendor collecting data?

No, and conflating the two is a common error in both directions. A vendor can receive a request — with an IP address, a user agent, a referring URL and whatever the payload carries — without setting a single cookie, and that transfer is processing regardless of storage. Equally, a cookie you set yourself is storage without any third-party transfer.

The gate therefore has to cover the request, not just the storage. Auditing the cookie list is a good check because cookies are easy to see, but a clean cookie list on a page that is still contacting six vendors before consent is not a compliant page.

How long should we wait before declaring a first visit clean?

Longer than feels necessary. Several vendors write cookies on a delay — after an idle callback, after a first interaction, or after a heartbeat that fires thirty seconds in — so a check performed immediately after load will miss them entirely and report a clean state that is not.

Wait at least a minute with the page in the foreground, then scroll and move the pointer without answering the banner, and re-read the list. Anything that appears during that period was written by something your gate did not hold, and the delay is usually why nobody had noticed it before.

Does clearing cookies on revocation undo the problem?

It is necessary and not sufficient. Deleting the cookies a vendor set removes the identifier from the device, which is the visible half; it does nothing about the data already transmitted, and it does nothing about the vendor’s own server-side record keyed to that identifier.

Do it anyway, because it is the part a regulator can verify from a browser, and pair it with the vendor’s own deletion or opt-out call where one exists. Note also that you can only clear cookies on your own domain — anything the vendor set on theirs is outside your reach entirely, which is worth stating plainly in your privacy notice rather than implying a completeness you cannot deliver.


Up: Architecting GDPR-Compliant Consent Gating