Google Tag Manager containers do not fail loudly. There is no error log, no red banner, no email from Google telling you that a quarter of your purchases stopped arriving on the 14th of last month. The container publishes, the site loads, and the dashboards keep drawing charts that are wrong.
Four failure families account for most of it. None of them are exotic, and all of them are invisible from inside the Tag Manager interface, which is why they survive for years.
Four things break conversion data in GTM: duplicate tags, which inflate; misconfigured triggers, which fire too often, too rarely, or at the wrong moment; broken variables, which send events with missing or wrong parameters that the platforms accept without complaint; and consent conflicts, which stop tags firing at all.
Preview mode will not find any of them. Preview shows you one session, on one browser, with your own consent choice, on the pages you thought to test. The failures live in the sessions you did not test. The only reliable detection method is reconciliation against your back office, plus a line-by-line read of the container.
What is on this page
Why containers drift
Nobody sits down and decides to break tracking. Containers degrade through ordinary business activity, and the pattern is consistent enough to predict.
Someone installs a platform app that adds its own Google tag, without knowing the container already has one. A developer hardcodes a pixel for a campaign and never removes it. The site replatforms and the data layer changes shape, but the variables still point at the old keys. An agency leaves, a new agency arrives, and rather than untangle the previous work they add their own parallel set of tags. A consent banner gets swapped for a cheaper one and the new one loads later in the page.
Every one of those changes is defensible on its own. Stacked over three years, they produce a container where nobody can say with confidence which tag owns which conversion, a condition with a name: overtagging.
Duplicate tags: the same conversion, counted twice
Duplication is the most common problem and the least alarming to look at, because it makes your numbers better. Revenue is up, conversion volume is up, and nobody files a ticket about good news.
It comes from three places, and they need different fixes.
Double installation
The same measurement ID is present twice on the page: once through GTM, once hardcoded in the theme, or once through a platform integration such as a Shopify channel app or a WordPress plugin. Every event on every page is doubled.
This one is easy to test and easy to miss, because a GTM-injected tag does not appear in the page source. Searching the HTML for G- finds the hardcoded copy and tells you nothing about the container. You need to check both.
Overlapping triggers
One tag, two triggers, both true on the same page. A purchase tag fires on a Page View trigger matching /thank-you and on a custom event trigger listening for purchase. Both conditions hold on the confirmation page, so two events leave the browser.
The variant of this that costs the most is the confirmation page reload. The buyer refreshes to read the delivery estimate, or leaves the tab open and comes back to it two days later, and the browser re-runs the script without a server request. Same order, second purchase event.
Browser and server both sending
The purchase fires from the browser through GTM, and the same purchase fires again from a server container or a backend integration. Each side is correct on its own. Together they double the count, and the second half is invisible in the browser because it never happens there.
For Meta this is what event_id exists for. For GA4 it is transaction_id. Sending both copies without a shared identifier is the single most expensive mistake in a hybrid server-side setup.
Transaction ID is a safety net, not a fix
Google Analytics deduplicates purchase events that carry the same transaction ID, which is why every ecommerce guide tells you to send one. That safety net catches a lot. It has two limits worth knowing.
The first is time. Deduplication holds for events that arrive close together. A buyer who reloads the confirmation page the following day can still produce a second counted purchase.
The second limit is the one that turns duplication into lost conversions, and it is the reason this section belongs in an article about missing data. Google's documentation is explicit that an empty string is not a safe placeholder: GA4 will deduplicate every purchase event that arrives with transaction_id="". If your data layer emits an empty transaction ID when the order object fails to populate, GA4 does not record those orders as separate purchases. It collapses them into one, so the revenue does not inflate. It disappears.
The test for all of this is a reconciliation. Export paid orders from your back office for a two week window, export GA4 purchases for the same window and time zone, and join on transaction ID. If GA4 is higher, you are duplicating. If GA4 is lower, read the next three sections.
Triggers: right tag, wrong moment
Trigger problems split into three kinds, and only one of them is visible in a normal test.
Fires too often
The classic is a Form Submission trigger set to All Forms. It fires on the search box, the newsletter footer, the login screen and the postcode lookup. Every one of those becomes a lead in Google Ads, and Smart Bidding starts optimising towards people who use your site search.
On single page applications the equivalent is a History Change trigger firing on filter and sort parameter changes, producing four page views for one product listing page.
Fires too rarely
This is the one that costs conversions outright, and it hides well because it usually works on the developer's machine.
GTM's Form Submission trigger has a Wait for Tags option, which delays the submission until dependent tags have fired or the timeout elapses, and a Check Validation option, which restricts the trigger to submissions that go through successfully. Both sound like obvious wins, and both have a failure mode.
Without Wait for Tags, a form that redirects on submit can navigate away before the conversion request leaves the browser. The tag fired, the request never completed, and nothing arrives.
With Check Validation, forms that are not built on native browser validation behave unpredictably. Because there is no standard for how forms are coded, the submission event frequently appears in preview mode even for a failed submission, and the reverse also happens on forms that block the native submit event entirely. Any form that posts over AJAX, sits inside an iframe, or is rendered by a third-party embed will not reliably produce gtm.formSubmit at all.
If your lead volume in Google Ads is meaningfully below the leads in your CRM, this is where to look first. If you want the ad platforms to learn from what those leads become rather than from the form fill alone, that is a separate build, covered in our guide to offline conversion tracking.
Fires at the wrong moment
GTM evaluates in a fixed order: container load, then DOM ready, then window loaded, then user interactions. A tag that reads a variable populated by a script running at DOM ready will resolve to undefined if it fires on container load. The tag still fires. The parameter is missing. Which brings us to the next section.
Variables: the failure nobody sees
Broken variables are the reason we tell clients that a green tick in preview mode proves almost nothing. A tag can fire perfectly on schedule and still send a useless payload, because GA4 and the ad platforms accept incomplete events without complaint. There is no rejection, no warning, no bounce. The event lands, the missing parameter is dropped, and the report shows (not set).
The data model merges, and that is the problem
GTM does not read the dataLayer array directly. It maintains an internal data model built by recursively merging every push. Plain objects merge with what is already there, while arrays and primitives replace it, which means values pushed early persist until something explicitly overwrites them.
The practical consequence: on an ecommerce site, product data from an earlier event bleeds into a later one. Without a ecommerce: null push before each new ecommerce event, the items array from the previous push stays in memory and appears in the next event, so an add to cart reports products that were never added. On single page applications, where the page never reloads and the data model is never cleared, this compounds across an entire session.
Version 1 or Version 2
Data Layer Variables have a version setting that most people never touch. Version 1 reads only the most recent push and cannot reach nested keys; Version 2 applies the recursive merge and can. For the items array, Version 1 is usually the safer choice, because it sidesteps the merge contamination described above. Version 2 is the default. That default is wrong for a lot of ecommerce containers.
Default values that hide the fault
Setting a default value on a variable feels like good hygiene. It is, until the default becomes the answer. A currency variable defaulting to EUR means your Swiss orders report in euros forever, and the failure never surfaces because there is no gap in the data to notice.
The related version of this is value arriving as a formatted string. "€49,00" is a string. GA4 and Google Ads want a number. Conversion value silently becomes zero, and value-based bidding optimises against nothing.
Consent Mode conflicts: tags that never fire
This is the newest of the four, and the one where the fix most people apply is the thing that breaks it.
GTM offers two separate consent mechanisms per tag, and they are not interchangeable. Built-in consent checks list the consent states a tag template reads in its own code; what the template does with them depends on the template. Additional consent checks list states that must all be granted for the tag to fire at all, and if any listed state is denied when the trigger goes off, the tag does not fire.
Here is the trap. Google's own tags already carry built-in consent checks and adjust their behaviour on their own. Google's documentation states plainly that if you have implemented consent mode and apply additional consent checks to Google tags at the same time, they will not work properly. Adding a belt to the braces does not make you safer. It removes the mechanism that was doing the work.
The mechanism that breaks is timing. If your CMP loads asynchronously, it may not run before your Google tags, so tags can be triggered before the visitor has interacted with the banner or before the consent update arrives. Once that has happened, granting consent later does not help: the tags do not fire, because consent was not granted at the moment they were first triggered.
Read that again if you configure containers for clients. A visitor accepts everything, browses for eleven minutes, buys, and the purchase tag never fires, because the tag's additional consent check evaluated as denied on page one and nothing re-evaluates it.
The rule we apply
Google tags get Additional Consent Checks set to No additional consent required, and rely on their built-in behaviour. Non-Google tags that have no built-in consent awareness, such as an email platform pixel or a heatmap script, get Require additional consent for tag to fire with the relevant storage types.
The CMP tag itself goes on the Consent Initialization trigger. Nothing else does. If you are setting this up from scratch, our Consent Mode implementation guide covers the defaults and the per-parameter consent requirements in full.
What Advanced Consent Mode does and does not buy you
Worth being precise, because this gets oversold. Under Advanced Consent Mode, Google tags do fire on rejection and send cookieless pings. Those pings feed conversion modeling. They do not attribute conversions on their own, and they are useless to you below the modeling thresholds.
GA4 behavioural modeling requires both conditions to hold: at least 1,000 events per day with analytics_storage denied, and at least 1,000 daily users sending events with analytics_storage granted. Google Ads conversion modeling is a separate mechanism with a separate bar, around 700 ad clicks over seven days per country and domain grouping. Most mid-market advertisers sit under one or both, which means a rejection is a genuine gap, not a modelled one. Anyone telling you Consent Mode recovers the data is describing a large advertiser's experience, not yours.
The admin side of this moved recently as well. Google's 15 June 2026 consent controls split changed how the setting behaves across linked GA4 and Google Ads accounts, which is worth checking if your container predates it.
Symptom to cause: a diagnostic table
Filter by failure family, or read the lot. The right hand column is where to look first, not a guaranteed answer.
| What you see | Usual cause | Where to look |
|---|---|---|
| GA4 revenue higher than the back office | Two collection paths for one purchase | Page source for a hardcoded measurement ID, platform apps, server container |
| Occasional double orders, no pattern | Confirmation page reloaded or restored from a background tab | Trigger conditions on the purchase tag, local storage guard |
| Google Ads leads far above CRM leads | Form trigger set to All Forms | Trigger conditions, Form ID and Form Classes variables |
| Google Ads leads far below CRM leads | Submission not detected, or page navigates before the request completes | Check Validation, Wait for Tags, iframe and AJAX forms |
| Page views inflated on a SPA | History Change firing on query parameter updates | History Change trigger conditions |
| Reports full of (not set) | Variable resolving undefined at fire time | Trigger timing against data layer push order |
| Wrong products on add to cart | Items array bleeding through the recursive merge | Missing ecommerce null push, Data Layer Variable version |
| Conversion value zero or missing | Value sent as a formatted string | Data layer value type, currency symbols, comma decimals |
| Conversions drop the week a new banner went live | Additional consent checks applied to Google tags | Consent Overview screen in the container |
| Some sessions track fully, others not at all | CMP loading after the Google tags on slower connections | CMP script placement, Consent Initialization trigger |
These faults interact, which is why fixing one at a time often fails to move the reconciliation number.
A self check you can run first
Before you pay anyone, including us, run this. It tells you whether there is a problem worth spending money on, and none of it requires a specialist.
Container triage
0 of 7 doneWhat an audit will not fix
We sell audits, so it is worth being clear about the edges.
- Data that was never collected. A fixed container starts producing correct numbers from the day it is published, not retroactively.
- The four platforms agreeing. GA4, Google Ads, Meta and your back office use different attribution models and different windows. Correct tracking narrows the gap. It does not close it.
- Consent rejection. If people decline, the events are gone, and modeling only helps at volumes most advertisers do not reach.
- A data layer that does not exist. If the site emits nothing usable, that is a development project, not a container fix, and the audit will say so.
- Ad blockers and browser restrictions. Server-side tagging reduces loss here. It does not make collection immune, because on a hybrid setup the first hop still starts in the browser. We covered the scale of the client-side problem in how ad blockers are destroying your analytics.
FAQ
Can preview mode find these problems?
It finds some trigger faults and some variable faults, in the exact session you are testing. It cannot find a second collection path you did not know about, a consent race that only happens on slow connections, or a form that fails on Safari. Preview is a debugging tool, not a coverage tool.
How much data is a broken container usually losing?
The honest answer is that it varies too much to quote a single figure, and any consultancy that gives you one before looking at your setup is quoting a case study. The reconciliation exercise in the checklist above gives you your own number, and that is the one worth acting on.
Do I need to rebuild the container from scratch?
Rarely. Most containers need restructuring, consistent naming, deduplication and a cleaner data layer, not a clean wipe. A full rebuild is occasionally the right call, and when it is, the reasoning should be written down, including what gets preserved. We set out how we scope that work in why hire a conversion tracking agency.
Will moving to server-side tagging solve this?
No, and moving a broken setup server-side usually makes it harder to debug. Server-side tagging is worth doing once the client-side foundation is correct. Before that, it adds a second place for the same faults to hide, plus a monthly bill. If you are weighing it up, start with what server-side tracking is, then the build and cost breakdown.
We use a consent management platform, so consent is handled. Right?
Having a CMP and having it configured correctly are different states. A properly installed banner combined with additional consent checks on Google tags is a configuration the CMP vendor did not ask for, and one Google's documentation warns against.
If you have run the reconciliation and the gap is uncomfortable, that is the point where an outside read pays for itself. A Voxxy tracking audit covers every tag, trigger, variable, event and conversion action in the container, ranked by estimated revenue impact rather than severity, and written so a developer can action it and a CMO can read it. You keep the report whether you hire us for the remediation or not.
Book a call and bring your reconciliation number, or send it over in writing. If the answer is that your setup is fine, we will tell you that instead.
Related reading
- What is overtagging? The duplication problem in full, with the detection method.
- What conversion tracking methods are best for your business? Which approach fits before you spend anything on a rebuild.
- Server-side GTM: what it is, how to configure it, and when it is worth the bill The next step once the container is clean.
- How to track website data without violating user privacy Consent Mode defaults, parameters and the compliance side.
- Case studies What these fixes changed for real accounts.
Sources
- Tag Manager Help: consent mode support and consent settings
- Tag Manager Help: unblock Google tags when using consent mode
- Analytics Help: minimise duplicate key events with transaction IDs
- Tag Manager Help: form submission trigger
- Simo Ahava: Consent Mode v2 for Google tags
- Simo Ahava: data layer variable versions explained
- Analytics Mania: form submission trigger not working
Related Posts
Why Hire a Conversion Tracking Agency?
Hiring a conversion tracking agency means accurate data, better campaign…


