Google Consent Mode vs IAB TCF v2.2 reference card

last verified · against Google Tag Platform, Ad Manager, Google Ads, and IAB TCF v2.2 docs as of 2026-07

Google Consent Mode vs IAB TCF v2.2: which to run, the TCF purpose-to-signal mapping, the 500ms CMP timeout, and the Additional Consent string, on one card.

What this is

Google Consent Mode and the IAB Europe Transparency and Consent Framework (TCF) v2.2 are two distinct consent-signalling systems: Consent Mode governs whether and how Google’s own tags collect and use data (via granted/denied signals), while TCF governs vendor-level transparency and legal basis through a Consent Management Platform (CMP), the Global Vendor List (GVL), and the TC String. This card states which to run, maps every TCF purpose to its Consent Mode effect, and lists the timeouts, ad-serving requirements, and Additional Consent format an implementer needs at the point of integration.

The two systems at a glance

Dimension Google Consent Mode IAB TCF v2.2
What it governs Whether/how Google’s own tags collect and use data Vendor-level transparency and legal basis
Core components 7 consent signals, each granted or denied CMP + Global Vendor List (GVL) + TC String
Primary audience Advertisers / measurement (Google Ads, GA4) Publishers monetizing with Google ad products
Signals reach Google via HTTP params gcs, gcd, dma, dma_cps The TC String, read by the CMP
Version note v2 added ad_user_data and ad_personalization v2.2 released May 2023; v2.3 April 2025

Google recommends implementing only ONE of the two, not both, to avoid unintended interactions. When signals conflict, Google takes the most conservative (most privacy-preserving) union of the signals.

Signal Controls Added
ad_storage Advertising storage such as cookies (web) or device identifiers (apps) v1
analytics_storage Analytics storage, for example visit duration v1
ad_user_data Consent to send user data to Google for online advertising v2
ad_personalization Consent for personalized advertising / remarketing v2
functionality_storage Not described in these sources v1
personalization_storage Not described in these sources v1
security_storage Not described in these sources v1

Every signal takes granted or denied. The four advertising/analytics types above the divider (ad_storage, ad_user_data, ad_personalization, analytics_storage) are the ones these sources detail; the remaining three are named in the seven-type list but not further described in these sources.

Default vs update, basic vs advanced

State When it is set
default Before the user interacts (set before any tag fires)
update After the user interacts with the consent banner
Mode Tag loading Data before consent
Basic Blocked until the user interacts Sends nothing beforehand, not even consent status
Advanced Loads immediately with defaults Cookieless pings even when consent is denied, enabling advertiser-specific modeling
Param Role
gcs Transmits the storage-consent choices
gcd Detailed consent; always sent
dma Named in the docs; value encoding not detailed in these sources
dma_cps Named in the docs; value encoding not detailed in these sources

The specific gcs/gcd value tables are widely reported by practitioners but are not published on the official Google page cited here. Treat community decodings as hints and confirm the values against the actual network requests your tags send.

TCF v2.2 taxonomy

Category Count
Purposes 11
Special Purposes 3
Features 3
Special Features 2
# Purpose Legal basis
1 Store and/or access information on a device Consent only
2 Use limited data to select advertising Consent or LI
3 Create profiles for personalised advertising Consent only
4 Use profiles to select personalised advertising Consent only
5 Create profiles to personalise content Consent only
6 Use profiles to select personalised content Consent only
7 Measure advertising performance Consent or LI
8 Measure content performance Consent or LI
9 Understand audiences through statistics or combinations of data from different sources Consent or LI
10 Develop and improve products Consent or LI
11 Use limited data to select content Consent or LI

Consent-only purposes (legitimate interest not permitted): 1, 3, 4, 5, 6. Consent-or-LI purposes: 2, 7, 8, 9, 10, 11.

Special Features and Special Purposes

Item Name Legal basis
Special Feature 1 Use precise geolocation data Consent only
Special Feature 2 Actively scan device characteristics for identification Consent only
Special Purpose 1 Ensure security, prevent and detect fraud, and fix errors Legitimate interest only
Special Purpose 2 Deliver and present advertising and content Legitimate interest only
Special Purpose 3 Save and communicate privacy choices Legitimate interest only

How Google is registered under TCF

Rule Ad Manager (publisher) Google Ads (advertiser)
Consent always required (not flexibly registered) 1, 3, 4 1, 3, 4
Legitimate-interest default unless CMP restricts to consent 2, 7, 9, 10 2, 5, 6, 7, 9, 10

The two Google pages list a slightly different flexible/LI-default set (Ad Manager: 2, 7, 9, 10; Google Ads: 2, 5, 6, 7, 9, 10). The difference likely reflects product scope and is not reconciled explicitly in the docs. In both cases: Google will not work via TCF if the TC String indicates personalization (Purposes 3 and/or 4) is permitted under legitimate interest, and Google interoperates with Special Features 1 and 2 only when appropriate disclosure is provided and users opt in.

Google reads the TC String via the CMP and maps denied TCF purposes to Consent Mode signals:

Denied TCF signal Resulting Consent Mode effect
Purpose 1 denied ad_storage = denied AND ad_user_data = denied
Purpose 3 denied ad_personalization = denied
Purpose 4 denied ad_personalization = denied
Purpose 7 denied ad_user_data = denied
Purpose 9 or 10 denied Google Signals feature disabled

The docs describe mapping only to the ad-related signals (ad_storage, ad_user_data, ad_personalization); deriving analytics_storage from the TC String is not described in these sources.

Ad-serving requirements via TCF (publisher)

Outcome What the CMP must capture
Personalized ads Consent for Purposes 1, 3, 4 plus legitimate interest for Purposes 2, 7, 9, 10
Non-personalized ads Consent for Purpose 1 plus legitimate interest for Purposes 2, 7, 9, 10
Limited ads only The fallback whenever Purpose 1 consent is absent, regardless of other consent

Separately, recording a Google Ads conversion through the TCF integration requires Purposes 7, 9 and 10 (satisfied by consent or legitimate interest, since Google is flexibly registered for them). Without them, Google Ads will not record the conversion.

Enabling TCF in Google tags

Item Value
Enable at website level window['gtag_enable_tcf_support'] = true; set before the Google tag / GTM code
Enable at CMP level TCData.enableAdvertiserConsentMode = true
CMP timeout No response within 500ms, or status error / stub / loading, means the tag proceeds with default consent settings
Combining Use TCF OR Consent Mode, not both; conflicts resolve to the most conservative union in favor of privacy
Item Value
Purpose Consent for Google Ad Technology Providers (ATPs) NOT on the IAB GVL; complements the TC String
ACv2 format [Version]~[Consented ATP IDs]~dv.[Disclosed ATP IDs], version 2
Example, consented 2~1.35.41.101~dv
Example, mixed 2~1.10~dv.2.3.4 (1 and 10 consented, others disclosed)
Example, all disclosed 2~~dv.1.2.3.4.10 (all disclosed, none consented)
ATP ID list https://storage.googleapis.com/tcfac/additional-consent-providers.csv
Who may mint it Only a TCF-registered CMP using its assigned CMP ID
Version ACv2 standard since December 2023 (v1 strings still supported)

Certification, tags, and deadlines

Item Value
Personalized ads in EEA/UK/CH (publisher) Requires a Google-certified CMP that integrates the IAB TCF; non-certified traffic may receive only non-personalized or limited ads
Deadlines EEA + UK 2024-01-16; Switzerland 2024-07-31; CTV inventory extended to July 2025
Automatic TC String forwarding GPT, GPT Passbacks, AdSense, Ad Exchange tags, IMA SDK, PAL communicate with the IAB CMP automatically; the Mobile Ads SDK reads the TC String from local storage
Tagless ad requests Manually pass gdpr={0,1} and gdpr_consent={tc string}; when an NPA signal and a TC String both appear, Google applies the most conservative setting

Gotchas

  1. Personalized ads or conversions silently stop while the banner looks fine → the CMP did not return a valid TC String within Google’s 500ms window, or returned error/stub/loading, so the tag fell back to defaults → load the CMP before Google tags and verify TCData status via the __tcfapi callback before relying on personalization.
  2. TCF and Consent Mode both set, behavior is unpredictable or double-restricts → both integrations were implemented at once, and Google resolves conflicts by taking the most conservative union → choose one path: enable gtag_enable_tcf_support OR set Consent Mode signals directly, not both.
  3. Personalized ads disabled despite many granted purposes → Purpose 1 consent is missing, so only Limited ads can serve regardless of other grants → capture explicit consent (not LI) for Purposes 1, 3 and 4.
  4. Personalization stays off even with LI configured for it → Google refuses TCF integration when the TC String signals legitimate interest for Purposes 3/4, and v2.2 removed LI as a legal basis for Purposes 3 to 6 → configure the CMP to request consent, not LI, for Purposes 3 and 4.
  5. A Google ad partner gets no consent though the banner was accepted → that vendor is an ATP not on the IAB GVL, so its consent lives in the Additional Consent string, not the TC String → use a Google-certified CMP that emits the ACv2 string and keep the ATP CSV in sync.
  6. Remarketing and conversion measurement for new EEA users stop growing after early 2024 → Consent Mode v2 signals ad_user_data and ad_personalization are not being passed → upgrade to Consent Mode v2 and pass both, in addition to ad_storage and analytics_storage, via a certified CMP.
  7. Conversions from EEA traffic are not recorded via TCF → Google Ads requires Purposes 7, 9 and 10 for conversion recording, and the CMP omits or restricts them → allow Purposes 7, 9, 10 (consent or LI) in the CMP configuration.

Quick recipes

enable-tcf.html
<!-- Website-level enable: MUST run before the Google tag / GTM container. -->
<script>
window['gtag_enable_tcf_support'] = true;
</script>
<!-- ...your Google tag (gtag.js) or GTM snippet loads AFTER this line... -->
enable-tcf-cmp.js
// Alternative to gtag_enable_tcf_support: enable at the CMP level instead.
// The CMP sets this on the TCData it exposes to Google tags.
TCData.enableAdvertiserConsentMode = true;
consent-mode-v2.js
// The OTHER integration path. Do NOT combine with gtag_enable_tcf_support.
// Denied-by-default state, set before any Google tag fires:
gtag('consent', 'default', {
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
analytics_storage: 'denied',
});
// Then update after the user interacts with the banner:
gtag('consent', 'update', {
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
analytics_storage: 'granted',
});
build-acv2.js
// ACv2 format: 2~[consented ATP IDs]~dv.[disclosed ATP IDs]
// Only a TCF-registered CMP may actually mint this; shown here for parsing/QA.
function buildAcV2(consented, disclosed) {
const c = consented.join('.'); // e.g. "1.35.41.101"
const d = disclosed.length ? 'dv.' + disclosed.join('.') : 'dv';
return `2~${c}~${d}`;
}
buildAcV2([1, 35, 41, 101], []); // "2~1.35.41.101~dv"
buildAcV2([1, 10], [2, 3, 4]); // "2~1.10~dv.2.3.4"
buildAcV2([], [1, 2, 3, 4, 10]); // "2~~dv.1.2.3.4.10"
verify-cmp-timing.js
// If the CMP does not return valid data within 500ms, or reports
// 'error' / 'stub' / 'loading', Google tags fall back to DEFAULT consent.
// Confirm the CMP is ready before relying on personalization.
// (__tcfapi signature: see the TCF v2.2 quick reference.)
const TIMEOUT_MS = 500;
let settled = false;
const timer = setTimeout(function () {
if (!settled) console.warn('CMP not ready in 500ms -> Google uses defaults');
}, TIMEOUT_MS);
window.__tcfapi('addEventListener', 2, function (tcData, success) {
const notReady = ['error', 'stub', 'loading'];
if (success && notReady.indexOf(tcData.cmpStatus) === -1) {
settled = true;
clearTimeout(timer);
// tcData is trustworthy here; safe to gate personalization on it.
}
});
tagless-ad-request.txt
# Tagless (server-to-server) ad requests must carry the IAB signals manually.
# gdpr = 0 (does not apply) or 1 (applies); gdpr_consent = the TC String.
https://securepubads.g.doubleclick.net/gampad/ads?...&gdpr=1&gdpr_consent=CPqABCD...ByxAAA
# If an NPA signal AND a TC String are both present, Google applies the most
# conservative setting.

Sources

Official pages these values were read from (read 2026-07-20):

Honesty notes. The gcs/gcd request-parameter encodings are not published on the Google page cited here; treat community value tables as hints. The flexible/LI-default purpose set differs between the Ad Manager guidance (2, 7, 9, 10) and the Google Ads page (2, 5, 6, 7, 9, 10) and is not reconciled in the docs. The docs describe TCF-to-Consent-Mode mapping only for ad-related signals, not analytics_storage. TCF v2.2 purpose and feature names were confirmed via Didomi’s summary as a mirror because the IAB Europe FAQ PDF did not parse as text; the authoritative machine-readable source is the GVL JSON at vendor-list.consensu.org. The specific advertiser-side Consent Mode v2 enforcement date sometimes cited as March 2024 comes from secondary sources; the official pages cited here document publisher certified-CMP/TCF deadlines instead.

Changelog

  • — Initial version, verified against official documentation.

dataLayer

0 events · 0 sent

    • home /
      writing /writing
      guides /guides
      work /#work
      about /about
      colophon /colophon
      toggle analyst mode ctrl+.
      print session receipt /#receipt