GA4 Consent Mode v2: Der gcd-Parameter, CMP-Wettläufe und serverseitiges Debugging
Teil 3 von 4 der Reihe Einwilligung richtig verdrahten

Inhalt
GA4 Consent Mode v2: Der gcd-Parameter entschlüsselt (Deep Dive in Network Requests)
In modernen Digital-Analytics-Architekturen erfordert die Validierung des Datenschutzes weit mehr als die reine Kontrolle, ob ein Cookie-Banner auf der Website sichtbar ist. Während der Standard-Parameter gcs in den Netzwerk-Requests von Google Analytics 4 (GA4) nur ein simples Gesamtergebnis liefert (wie etwa g110 oder g111), verbirgt sich die exakte Logik des Google Consent Mode v2 im kryptischen gcd-Parameter (z. B. 11r1r1r1r5).
Diese technische Analyse schlüsselt die Bit-Logik des gcd-Strings präzise auf, zeigt Methoden zum Debugging im Server-Side Google Tag Manager (ssGTM) und demonstriert, wie sich Race-Conditions zwischen Consent Management Plattformen (wie Usercentrics) und dem initialen Pageview zuverlässig identifizieren lassen.
1. Die Struktur des gcd-Parameters
Im Gegensatz zum gcs-Wert, der ausschließlich meldet, ob Werbe- oder Analyse-Cookies zugestimmt wurde, bildet der gcd-Parameter den vollständigen Lebenszyklus jedes einzelnen Consent-Signals ab. Er zeigt exakt, ob ein Status durch einen Default-Befehl initialisiert, per User-Interaktion aktualisiert (Update) oder gar nicht konfiguriert wurde.
Ein typischer gcd-String folgt immer derselben Struktur: 11<ad_storage>1<analytics_storage>1<ad_user_data>1<ad_personalization>5
| Buchstabencode | Consent-Status | Technische Bedeutung |
|---|---|---|
l | Nicht gesetzt | Kein Default und kein Update; Consent Mode ist für dieses Signal nicht konfiguriert. |
p | Denied (Default) | Default-Status abgelehnt, bislang kein Update eingegangen. |
q | Denied (Default + Update) | Default-Status abgelehnt, Update ebenfalls abgelehnt. |
r | Granted (Update) | Default-Status abgelehnt, Update auf Zustimmung. |
t | Granted (Default) | Default-Status zugestimmt, bislang kein Update eingegangen. |
u | Denied (Update) | Default-Status zugestimmt, Update auf Ablehnung. |
v | Granted (Default + Update) | Default-Status zugestimmt, Update ebenfalls Zustimmung. |
m | Denied (Update) | Kein Default-Befehl, Update auf Ablehnung. |
n | Granted (Update) | Kein Default-Befehl, Update auf Zustimmung. |
Der Wert gcd=11p1p1p1p5 steht beispielsweise für eine restriktive Ausgangslage, bei der alle vier Parameter (ad_storage, analytics_storage, ad_user_data, ad_personalization) per Default auf Ablehnung stehen und noch kein Update eingegangen ist (p). Ein String wie gcd=11r1r1r1r5 verifiziert hingegen, dass ein Update-Event erfolgreich verarbeitet wurde und alle vier Signale vom abgelehnten Default auf Zustimmung gewechselt sind (r). Ein String aus v-Codes beschreibt dagegen einen anderen Fall: Zustimmung bereits im Default, durch das Update bestätigt.
2. Identifikation von CMP-Race-Conditions
Ein häufiger Architekturfehler in Analytics-Setups ist eine Race-Condition zwischen der Initialisierung der CMP (z. B. Usercentrics) und dem Auslösen des ersten GA4-Configuration-Tags. Wenn wiederkehrende Besucher mit bereits gespeicherter Zustimmung beim ersten Pageview im Netzwerk-Request den Code p statt r aufweisen, wurde das Tracking-Tag abgefeuert, bevor die CMP das Update-Event in den DataLayer pushen konnte.
- Symptom: Der erste Pageview-Hit trägt
gcd=11p1p1p1p5(Default Denied, noch kein Update), nachfolgende Event-Hits jedochgcd=11r1r1r1r5(Default Denied, Update auf Zustimmung). - Ursache: Das GA4-Tag wird über All Pages oder Consent Initialization ausgelöst, ohne die asynchrone Status-Auflösung der CMP abzuwarten.
- Lösung: Tracking-Tags ausschließlich an spezifische CMP-Events (wie
consent_status) koppeln oder den Parameterwait_for_updatemit 500 ms Latenz im Default-Snippet setzen.
3. Server-Side GTM Debugging & Validierung
Im Server-Side Google Tag Manager (ssGTM) dient der eingehende GA4-HTTP-Request als Datenträger für sämtliche nachgelagerten Marketing-Tags wie Meta Conversions API (CAPI) und Google Ads. Die Prüfung des gcd-Parameters im ssGTM Preview Mode ist zwingend erforderlich, um illegale Datenweiterleitungen zu unterbinden.
// Beispiel: ssGTM Custom Variable zur Validierung von ad_user_data
// Struktur: 11<ad_storage>1<analytics_storage>1<ad_user_data>1<ad_personalization>5
// ad_user_data liegt damit auf Index 6; Index 7 ist die feste Trennziffer "1"
const gcd = getRequestQueryParameter("gcd");
const adUserData = gcd ? gcd.charAt(6) : "";
// Granted-Codes: t (Default), v (Default und Update), r (Default denied, Update granted), n (kein Default, Update granted)
if (adUserData === "t" || adUserData === "v" || adUserData === "r" || adUserData === "n") {
return true; // ad_user_data liegt als granted vor
}
return false;
Durch die Implementierung serverseitiger Trigger-Bedingungen auf Basis des decodierten gcd-Status bleibt die Datenarchitektur absolut rechtskonform (DSGVO & DMA) und verhindert zuverlässig den Versand von Marketing-Payloads, solange sich der Consent im Default-Denied-Zustand befindet.
Einwilligung richtig verdrahten
- Google Consent Mode v2 implementieren
- Wie cookielose Pings im Google Consent Mode funktionieren
- GA4 Consent Mode v2: Der gcd-Parameter, CMP-Wettläufe und serverseitiges Debugging
- Consent-Status an Server-Side GTM übergeben
2 Kommentare
die Aufschlüsselung der Buchstaben ist die erste Darstellung, mit der sich ein
gcd-Wert tatsächlich lesen lässt — die Unterscheidung zwischen „kein Standard“ und „Standard abgelehnt“ ist ja gerade der interessante Teil.Zur Servervariablen habe ich eine Rückfrage, weil sie mit
charAt(6)auf eine feste Position zugreift. Was passiert bei einer Anfrage, die den Parameter gar nicht mitbringt?Dann ist
gcdleer,charAt(6)liefert eine leere Zeichenkette, und die Variable gibtfalsezurück. Das Verhalten ist richtig — im Zweifel nicht senden —, aber es verdeckt einen Unterschied, der später gebraucht wird.Ein fehlender Parameter bedeutet nämlich nicht „abgelehnt“, sondern „diese Anfrage stammt nicht aus dem erwarteten Aufbau“: ein anderer Client im Server-Container, ein Treffer aus dem Measurement Protocol, ein Proxy, der Parameter kürzt. Wer beides gleich behandelt, sucht die Ursache später in der Einwilligung statt in der Herkunft der Anfrage.
Zwei kleine Ergänzungen lösen das: den Fall
gcdleer eigens protokollieren statt ihn infalsezu verschmelzen, und die Positionsannahme absichern, indem die Länge geprüft wird, bevor gelesen wird. Der Aufbau der Zeichenkette ist nicht als dauerhafte Zusage dokumentiert — eine Auswertung, die auf Position 6 zeigt, gehört deshalb an eine Stelle, an der auffällt, wenn sich dort etwas ändert.