GA4 + GTM Measurement Audit and Consent-Mode Root-Cause Diagnosis
The client reported that GA4 'never worked' for their marketing site. Working from GTM container exports, GA4 admin and reports, and live-site inspection, I confirmed the marketing property ([property id]) was empty while a separate product property ([property id 2]) recorded 15,742 sessions in 28 days. GTM (GTM-XXXXXXX) fired G-XXXXXXXX and G-XXXXXXXX, but three of the marketing property's four streams pointed at measurement IDs the site never sends to. The root cause: a correct Consent Mode default (denied, wait_for_update) with no Cookiebot 'update' to grant analytics_storage, so GA4 never collected on client.com, corroborated by Tag Assistant, DebugView (non_personalized_ads=0) and a manual consent test. I delivered a nine-page branded audit with six severity-ranked findings, a recommended target-state architecture, and a sequenced remediation roadmap, generated through a reusable HTML-to-PDF pipeline with automated QA.
A correct consent default with no update bridge: the tags were installed, the site was live, and GA4 collected nothing.
Role: Sole auditor, diagnostician and deliverable author
The Problem
The client reported that GA4 'never worked effectively' and that they could not see marketing results. The property a stakeholder would naturally open to judge marketing performance was empty, undermining trust in all reporting and any campaign optimization.
The marketing site client.com was not being measured in GA4 despite GTM (GTM-XXXXXXX), the GA4 marketing tag (G-XXXXXXXX) and Google Ads (AW-XXXXXXXXX) all being installed and a Consent Mode default block being present. Consent Mode default was set to denied with wait_for_update, but no consent 'update' bridge propagated Cookiebot acceptance to Google, so GA4 stayed denied and did not collect.
The tags looked correctly installed, and Consent Mode default was genuinely implemented, so surface checks suggested everything was fine. The account was also fragmented across seven GA4 properties with overlapping streams and measurement IDs, making it easy to open the wrong (empty) property and wrongly conclude nothing was firing. No CRM access was in scope, so Google Ads had to serve as the reference source of truth.
Approach & Architecture
Audited the live GA4 properties and the GTM container export directly, cross-checked live behaviour on client.com with Google Tag Assistant and a manual accept/decline consent test, and separated confirmed facts from labelled 'Summit Chase assessment' interpretation. Root cause was isolated to a missing Cookiebot-to-Consent-Mode update. Produced a 9-page branded Summit Chase PDF with six severity-ranked findings, a recommended target-state architecture, and a remediation roadmap.
Diagnostic pipeline over three evidence sources: (1) GTM container JSON export parsed for tag/trigger/variable inventory and which GA4 measurement IDs receive data; (2) GA4 admin + reports (Traffic acquisition, Pages/Hostname, Key events, change history) to see which property/hostname actually collects; (3) live-site inspection of the rendered HTML consent stack (Cookiebot uc.js, GTM, beforeInteractive Consent Mode default) plus Tag Assistant. Findings were rendered into a branded HTML template converted to PDF via a Playwright/Chromium pipeline.
Key Decisions & Trade-offs
Hardest Part
Reconciling that Consent Mode default was correctly present yet the marketing property was empty. Resolved by identifying the absent consent 'update' bridge from Cookiebot to Google, corroborated by DebugView showing only page_view/session_start/user_engagement with non_personalized_ads=0 after acceptance, Tag Assistant's CMP-may-be-blocking warning, and the empty hostname data for client.com.
Technical Detail
Seven-property GA4 estate under org 'the client Ltd'; marketing property holds 4 web streams each with a distinct measurement ID; recommended target model is one intended property per surface (marketing vs product) with one authoritative measurement ID each and retirement of streams/IDs the site never sends to.
Deliverable rendered with Playwright/Chromium to PDF (Letter, print_background, prefer_css_page_size, full-bleed @page cover, running footer via display_header_footer). Verification via pdftotext, pdf2image and PIL ink/pixel analysis.
Google Tag Assistant on client.com; GA4 DebugView; manual cookie accept/decline test; verification of the final PDF for page count, blank pages (per-page ink %), absence of em dashes/arrows/approx symbols, absence of other-client names and customer PII, and presence of all IDs and figures.
Code
gtag('consent', 'default', { 'analytics_storage': 'denied', 'ad_storage': 'denied', 'ad_user_data': 'denied', 'ad_personalization': 'denied', 'wait_for_update': 2000 // wait for Cookiebot to update consent settings
});pg.goto(url, wait_until='networkidle'); pg.wait_for_timeout(1500) pg.pdf(path=out, format='Letter', print_background=True, prefer_css_page_size=True, display_header_footer=True, header_template='<div></div>', footer_template='<div style="...">Summit Chase · Confidential, Prepared for the client ... Page <span class="pageNumber"></span> of <span class="totalPages"></span></div>')
im=Image.open(U+'Screenshot_2026-08-03_at_11_27_14_AM.png'); W,H=im.size
c=im.crop((int(0.36W), int(0.30H), int(0.995W), int(0.74H)))
c.save('eng/dbg_com.png')The entire diagnosis and deliverable were produced inside an AI coding environment: parsing the GTM container JSON, reading and cropping evidence screenshots programmatically, generating a branded HTML report, rendering it to PDF with Playwright, and self-verifying the output (page count, blank-page ink detection, banned-character scan, PII/other-client leak scan).
Repeatable audit-to-branded-PDF pipeline (HTML template + CSS design system + Playwright render + automated QA checks for blank pages, AI-tell characters, and client/PII leakage).
Measured Results
Isolated the root cause of a client's long-standing 'GA4 doesn't work' complaint to a missing Cookiebot-to-Consent-Mode update, plus severe property/stream fragmentation and non-registering conversions. Delivered a nine-page branded audit with six severity-ranked findings, a recommended target-state architecture, and a sequenced remediation roadmap. No performance uplift was measured in-chat; the deliverable was diagnostic and advisory.
| Metric | Value | Before | Source |
|---|---|---|---|
| Sessions in product property (28d, 6 Jul2 Aug 2026) | 15,742 | n/a | GA4 Traffic acquisition report |
| Sessions in marketing property (28d) The single session originated on client.io, not client.com | 1 | n/a | GA4 Traffic acquisition report |
| Views in product property (28d) | 85,177 | n/a | GA4 Pages/Hostname report |
| Key-event occurrences in product property (28d) Attributable to Social_Sign_Up, the only key event registering data | 144 | n/a | GA4 Traffic acquisition report |
| Session key-event rate | 0.41% | n/a | GA4 |
| GTM container tags | 103 (98 active, 5 paused) | n/a | GTM container export GTM-XXXXXXX workspace 203 |
| GTM triggers / variables | 64 triggers, 26 variables | n/a | GTM container export |
| GA4 properties in org | 7 | n/a | GA4 property list screenshot |
| Marketing-property streams / measurement IDs 3 of 4 point at IDs the container never sends to | 4 | n/a | GA4 admin |
| Anomalous session | 700 views / 1 user / ~1h19m engagement | n/a | GA4 Pages report |
| Final PDF length | 9 pages | n/a | pdf2image page count |
Every figure above was recorded during the work itself. Where no number was measured, none is claimed.