tagora

Consent Mode: how it works in the container, and why absence proves nothing

Consent Mode is visible in a container in four different forms — and the most common way to implement consent is not visible there at all.

What it actually does

Consent Mode does not decide whether a tag fires. It gives tags a state to adapt to. Google tags read four v2 signals — ad_storage, analytics_storage, ad_user_data, ad_personalization — plus functionality_storage, personalization_storage and security_storage, and change their behaviour accordingly.

Basic implementations withhold the tag entirely until consent is granted. Advanced lets the tag fire in a restricted mode: no cookies written, a cookieless ping sent so Google can model the conversion it did not observe. The distinction matters commercially — advanced mode is what preserves modelled conversions — and it is not reliably visible from outside.

The state has two moments: a default, set before any tag runs, and an update, sent when the visitor chooses. Getting the default wrong is the common failure, because a default of granted means the visitor's choice arrives after the tags it was supposed to gate.

The four ways it shows up in a container

There is no single flag. A published container can carry consent in four independent forms, and a real implementation often uses only one:

1. A default state set in the container. The Consent Mode initialisation, visible as gtm.init_consent and related keys in the parsed container data.

2. Per-tag gating. Individual tags carry a consent requirement — in the runtime this is a list on the tag itself, e.g. ["list", "analytics_storage"] — and GTM holds the tag back until that type is granted. This is the most concrete form: it names which tag waits for what.

3. A consent platform referenced by name. OneTrust, Cookiebot, Usercentrics, Didomi, TrustArc and others appear in the container when their template or their events are used.

4. gtag consent calls in custom code. gtag('consent', 'default', {...}) or 'update', written into a Custom HTML tag.

Measured across our corpus, each of these appears in a different slice of containers and none of them is universal: a default state in roughly 22%, per-tag gating in 12%, a named platform in 15%, a declared default or update in 17%.

A detection trap worth knowing about

gtm.init_consent appears in the raw text of every container served by Google, because it is part of the runtime library shipped to everyone — not evidence that this container configured anything.

It only discriminates when you parse the container and look inside the data object rather than grepping the file. A detector built on the raw source would report consent configuration on 100% of the web and feel confident about it.

This is the same shape as server_container_url, which is interned as a parameter name in every container's string table whether or not a value was ever set. Reading GTM from outside means routinely distinguishing the vocabulary the runtime always ships from the configuration a particular team chose.

Why we no longer flag its absence loudly

This audit used to raise a finding whenever four Consent Mode markers were missing, and it fired on 67.9% of all containers measured, framed in terms of EU exposure. That was wrong, and worth stating plainly rather than quietly fixing.

Consent is legitimately implemented in ways a container cannot show. A consent platform that blocks scripts before GTM loads enforces consent perfectly while leaving no trace in the container. So can page-level gtag calls, or a dataLayer the site controls.

Widening detection to all four signals moved the figure from 67.9% to 52.0% — roughly 5,900 containers that had been flagged for something we had no evidence about. Where we do find a signal, we now report which one it is (44.8% of containers) instead of only reporting silence.

The general rule this taught us: a finding that fires on absence needs the inverse of the usual test. Not “does this fire on everything?” but “does absence in the artifact actually mean absence in the world?” Here it did not, for about a third of the containers we were accusing.

What we report, and what we will not

We report which consent signals a container carries, and name them, so you can check them against what you meant to deploy. Where none of the four is present we say so — and say in the same breath that enforcement outside the container is invisible to us.

We will not tell you whether your configuration is correct. That depends on where your visitors are, what you told them, what your consent platform actually reports, and what your counsel advised. None of that is in a JavaScript file, and an audit tool that grades your GDPR position from one is selling confidence it does not have.

See this on a real container. No login, no signup.

Run a container check

Related