LW IT Solutions
« Blog Overview /Digital Analytics / GA4 Consent Mode v2: The gcd Parameter,...
Read this article in other languages:

GA4 Consent Mode v2: The gcd Parameter, CMP Race Conditions and Server-Side Debugging

Part 3 of 4 in the series Wiring consent correctly

GA4 Consent Mode v2: The gcd Parameter, CMP Race Conditions and Server-Side Debugging
Contents
  1. GA4 Consent Mode v2: Decoding the gcd Parameter (A Network Request Deep Dive)
  2. 1. The Anatomy of the gcd Parameter
  3. 2. Identifying CMP Race Conditions
  4. 3. Server-Side GTM Debugging & Validation
  5. Questions and answers
  6. Sources

GA4 Consent Mode v2: Decoding the gcd Parameter (A Network Request Deep Dive)

In modern digital analytics architectures, verifying privacy compliance requires more than inspecting whether a cookie consent banner is displayed. While the standard gcs parameter in Google Analytics 4 (GA4) network requests provides a basic overview of consent (such as g110 or g111), it lacks granular visibility into the underlying state machine. The true complexity of Google Consent Mode v2 is encoded within the cryptic gcd parameter (e.g., 11r1r1r1r5).

This technical deep dive breaks down the bit-logic of the gcd string, explains methods for debugging consent signals in Server-Side Google Tag Manager (ssGTM), and demonstrates how to identify race conditions between Consent Management Platforms (such as Usercentrics) and the initial pageview.

1. The Anatomy of the gcd Parameter

Unlike gcs, which only reports whether advertising or analytics storage is granted or denied, the gcd parameter reveals the complete lifecycle of each consent signal. It indicates whether a parameter was set by a default command, updated by a user action, or left unconfigured.

A typical gcd parameter string follows a structured pattern: 11<ad_storage>1<analytics_storage>1<ad_user_data>1<ad_personalization>5

Letter CodeConsent StateOrigin / Meaning
lNot setNo default and no update; Consent Mode is not configured for this signal.
pDenied (Default)Default state denied, no update received yet.
qDenied (Default + Update)Default state denied, update also denied.
rGranted (Update)Default state denied, update granted.
tGranted (Default)Default state granted, no update received yet.
uDenied (Update)Default state granted, update denied.
vGranted (Default + Update)Default state granted, update also granted.
mDenied (Update)No default command, update denied.
nGranted (Update)No default command, update granted.

Google does not officially document these letter codes; the table is based on observed behaviour and may stop being accurate when the tags change. For example, the value gcd=11p1p1p1p5 translates to a strict initial state in which all four consent parameters (ad_storage, analytics_storage, ad_user_data, ad_personalization) are denied by default and no update has arrived yet (p). Conversely, gcd=11r1r1r1r5 confirms that an update event has successfully fired, switching all four signals from the denied default to granted (r). A string made up of v codes describes a different case again: granted already at the default stage and confirmed as granted by the update.

The gcd string 11r1r1r1r5 as ten cells with the letters for ad_storage, analytics_storage, ad_user_data and ad_personalization at positions 2, 4, 6 and 8, a legend of the denied, granted and unset letters, three cards on the CMP race from symptom to wait_for_update, and the server-side check of position 6
How to read gcd: four letter positions, nine letter codes and the race between the CMP and the first pageview.

2. Identifying CMP Race Conditions

A common architectural failure in web analytics is a race condition between the CMP (e.g., Usercentrics) and the firing of the first GA4 configuration tag. If a returning user with stored consent visits a page, but the network request contains p codes instead of r codes, the tracking tag executed before the CMP could push the consent update to the DataLayer.

  • Symptom: First pageview request carries gcd=11p1p1p1p5 (default denied, no update yet), while subsequent events carry gcd=11r1r1r1r5 (default denied, update granted).
  • Root Cause: The GA4 tag triggers on standard All Pages (Page View) or Consent Initialization without waiting for asynchronous CMP state resolution.
  • Architectural Fix: Configure standard tracking tags to fire strictly on custom CMP events (such as consent_status) or utilize the wait_for_update parameter with a 500ms threshold in the default consent snippet.

3. Server-Side GTM Debugging & Validation

In Server-Side Google Tag Manager (ssGTM), incoming GA4 HTTP requests serve as the carrier for all downstream tags, including Meta Conversions API (CAPI) and Google Ads Conversion Tracking. Inspecting the gcd parameter within the ssGTM Preview Mode is critical to prevent non-compliant data forwarding.

// Example: Custom Variable logic in ssGTM to check the ad_user_data state
// Structure: 11<ad_storage>1<analytics_storage>1<ad_user_data>1<ad_personalization>5
// ad_user_data therefore sits at index 6; index 7 is the fixed separator "1"
const gcd = getRequestQueryParameter("gcd");
const adUserData = gcd ? gcd.charAt(6) : "";
// Granted codes: t (default), v (default and update), r (denied by default, granted by update), n (no default, granted by update)
if (adUserData === "t" || adUserData === "v" || adUserData === "r" || adUserData === "n") {
  return true; // ad_user_data is granted
}
return false;

By enforcing server-side trigger rules based on the decoded gcd state, data pipelines remain fully compliant with GDPR and the Digital Markets Act (DMA), ensuring zero marketing payloads are dispatched when consent remains in a default denied state.

Questions and answers

Does the letter l in the gcd string also appear when the default command runs after the first pageview, or only when a signal was never set?

Both produce the same letter, at least by the reading common among practitioners, since Google does not document the gcd parameter officially. That is what makes it awkward to read.

l records what the tag could see at the moment it assembled the request. A default that arrives after the pageview has left is indistinguishable from one that was never written, because the request is already gone. So the letter alone does not separate the two cases.

The pattern across the four positions does. A late default is late for all four signals at once — a timing problem does not pick some of them and spare the rest. When some positions carry a proper letter and others show l, the signals behind the l are missing from the consent commands themselves, most likely from an incomplete default command. That is easy to overlook because nothing fails: the tag fires, the request goes out, and only the letter says that those signals were never set.

Wiring consent correctly

  1. How to Implement Google Consent Mode v2
  2. How Cookieless Pings Work in Google Consent Mode
  3. GA4 Consent Mode v2: The gcd Parameter, CMP Race Conditions and Server-Side Debugging
  4. How to Pass Consent Status to Server-Side GTM
Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

Write a comment

Differing figures from other accounts and questions about the setup are welcome here.

The email address is not published. Required fields are marked with an asterisk.

Articles & categories

CCTV

Follow this category by RSS

Cloud & AI

All 17 articles in this category Follow this category by RSS

Data Privacy

All 19 articles in this category Follow this category by RSS

Digital Analytics

All 58 articles in this category Follow this category by RSS

Digital Marketing

All 37 articles in this category Follow this category by RSS

IT & Networks

All 18 articles in this category Follow this category by RSS

Music Production

All 17 articles in this category Follow this category by RSS

Raspberry PI

Follow this category by RSS

SaaS & Internet Earning

Follow this category by RSS

Smart Home

All 18 articles in this category Follow this category by RSS

Web Development

All 11 articles in this category Follow this category by RSS

WordPress Plugins & Tricks

All 14 articles in this category Follow this category by RSS