GTM 11 min read

7 Common GTM Mistakes That Break Your Analytics (And How to Fix Them)

The most expensive Google Tag Manager mistakes we see in client audits — duplicate tags, broken data layers, missing variables, and triggers that fire on the wrong pages.

A
Aumlytics Team
·

After auditing dozens of GTM containers, the same mistakes appear over and over. Some are innocent setup errors. Others are ticking time bombs — containers that look like they’re working until someone checks the data and finds three years of inflated sessions and double-counted conversions.

Here are the seven most damaging GTM mistakes we find in client containers, and exactly how to fix each one.


Mistake #1: Duplicate Tags Firing on Every Page

What it looks like: GA4 pageview events showing up twice in GA4 DebugView. Session counts are 1.5–2x higher than your actual traffic. Reports look inflated but you can’t figure out why.

Why it happens:

  • Someone installed the GA4 tag via GTM and hardcoded the gtag.js snippet in the page <head>
  • A second GTM container was added to the site without removing the first
  • The GA4 Configuration Tag was duplicated inside the container (two tags with the same Measurement ID)

How to diagnose:

Open Chrome DevTools → Network tab → filter by collect? or g/collect. If you see two requests firing on every pageview, you have a duplicate.

// In the browser console, check how many GA4 instances are running:
window.dataLayer.filter(d => d[0] === 'config')
// Should show ONE entry per page load. Multiple = duplicates.

Also check the page source (Ctrl+U) and search for G-XXXXXXXXXX (your Measurement ID). It should appear only once — inside the GTM script.

How to fix:

  1. Search the site’s codebase for the Measurement ID — remove any hardcoded gtag.js or ga.js snippets
  2. Inside GTM, check for duplicate Configuration Tags: GTM → Tags → search your Measurement ID
  3. Verify only one GTM container snippet is on the page

Reference: GA4 Deduplication in GTM


Mistake #2: The All Pages Trigger on Conversion Tags

What it looks like: Your “thank you page” event or purchase event fires on every page, not just the confirmation page. Your conversion numbers are wildly inflated.

Why it happens: Someone created a conversion tag and used the All Pages trigger instead of a page-specific trigger. This is one of the most common mistakes made by developers who are new to GTM.

How to diagnose:

In GTM Preview mode, navigate to your homepage. If your conversion tag (e.g., GA4 - Purchase Event) fires on the homepage — it’s broken.

How to fix:

Create a proper trigger for confirmation/thank-you pages only:

  1. GTM → Triggers → New
  2. Trigger Type: Page View
  3. Fire on: Some Page Views
  4. Condition: Page Pathcontains/order-confirmation (or your actual path)

For e-commerce, the better approach is to use a dataLayer event trigger:

// Push this from your order confirmation page:
window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'T_12345',
    value: 59.99,
    currency: 'USD',
    items: [...]
  }
});

Then in GTM, trigger on Custom Event → Event name: purchase.

Reference: GTM Trigger types


Mistake #3: Missing or Broken dataLayer Variables

What it looks like: Your GA4 events fire, but custom dimensions are blank. Product names, categories, prices are missing from e-commerce reports. You see undefined or (not set) in GA4.

Why it happens: GTM variables are referencing dataLayer keys that either:

  • Don’t exist (typo in the key name)
  • Haven’t been pushed yet when the tag fires
  • Are nested incorrectly (e.g., ecommerce.items[0].item_name vs ecommerce.items.0.item_name in GTM variable syntax)

How to diagnose:

In GTM Preview, click on a tag that’s supposed to send product data. In the Variables tab, look for variables showing as undefined.

Also check the dataLayer panel — expand the relevant event and verify the key names match exactly what your GTM variables reference.

Common variable path issues:

What you wantGTM variable path
ecommerce.valueecommerce.value
First item’s nameecommerce.items.0.item_name
ecommerce.items[0].priceecommerce.items.0.price

GTM uses dot notation for nested objects. Bracket notation ([0]) doesn’t work in GTM variable paths.

How to fix:

  1. Open GTM Preview → click the event → Variables tab
  2. Find any variable showing undefined
  3. Cross-reference the variable’s Data Layer Variable Name with the actual dataLayer push from your developer
  4. Correct any typos or nesting mismatches

For debugging, add this to your browser console:

// See everything in the dataLayer
window.dataLayer.forEach((entry, index) => {
  console.log(index, JSON.stringify(entry, null, 2));
});

Mistake #4: Tags Firing in Preview/Debug Mode But Not in Production

What it looks like: Everything works perfectly in GTM Preview. You publish. GA4 DebugView stops showing events. Your live reports never see the data.

Why it happens (three common causes):

A) Tag blocked by Content Security Policy (CSP) Your site’s CSP header blocks GTM’s domains from loading scripts or making requests. GTM works in Preview because Preview injects differently.

Check: Open DevTools → Console. Look for CSP errors like:

Refused to load script from 'https://www.googletagmanager.com'

Fix: Add GTM’s domains to your CSP script-src and connect-src directives:

script-src 'self' https://www.googletagmanager.com;
connect-src 'self' https://www.google-analytics.com https://analytics.google.com;

B) Trigger fires on URL pattern that doesn’t exist in production Your trigger uses Page URL contains staging.yoursite.com or a development path that doesn’t exist live.

Fix: Review all trigger conditions. Remove environment-specific URL conditions.

C) Tag never published (Draft status) GTM containers have versions. If a tag is in a workspace but no new version was published, it won’t run on the live site.

Fix: GTM → Submit → Publish new version. Verify the live container version number matches.


Mistake #5: Cross-Domain Tracking Not Configured

What it looks like: Users who move from yoursite.com to shop.yoursite.com (or to a payment processor) show up as two separate sessions. Conversion attribution is broken — GA4 attributes the purchase to (direct) instead of the original traffic source.

Why it happens: GA4 and GTM need explicit configuration to pass the _ga session cookie across domains.

How to diagnose:

  1. In GA4 → Reports → Traffic Acquisition, check if a huge percentage of conversions come from (direct) / (none)
  2. This is a red flag — real users rarely type URLs directly before purchasing

How to fix in GA4:

  1. GA4 → AdminData Streams → your web stream
  2. Configure tag settingsConfigure your domains
  3. Add all domains that should share session data:
    • yoursite.com
    • shop.yoursite.com
    • checkout.paymentprovider.com (if applicable)

How to fix in GTM:

If using GTM’s GA4 Configuration Tag:

  1. Open your GA4 Configuration Tag
  2. Fields to Set → Add field:
    • Field Name: linker
    • Value: {"domains": ["shop.yoursite.com", "yoursite.com"]}

Reference: GA4 cross-domain measurement


Mistake #6: Excluding Internal Traffic But Not Bot Traffic

What it looks like: Your traffic numbers look healthy, but engagement rate is unusually low. Bounce rate is high from certain sources. Your own visits inflate session counts.

Why it happens: Most people know to exclude their own IP in GA4, but forget about:

  • Office IPs (when the team works from an office)
  • Contractor and agency IPs
  • Bot and crawler traffic
  • Staging/preview environments

How to fix internal traffic:

In GA4:

  1. AdminData Streams → your stream → Configure tag settings
  2. Define internal traffic → add your IP ranges
  3. AdminData filtersInternal Traffic → set to Active

In GTM (alternative approach): Create a Lookup Table variable that returns true for known internal IPs, then add an exception trigger to all tags.

How to fix bot traffic:

GA4 automatically filters known bots (IAB list), but unknown bots slip through.

  1. GA4 → AdminReporting Identity
  2. Verify “Filter out known bots and spiders” is enabled (it should be by default)

For additional bot filtering, create a GA4 audience exclusion or use a custom filter:

// In GTM, block tags from firing on headless browsers
// (Many bots don't have userAgent strings with standard browser identifiers)
{{JS - Is Not Bot}} variable:
function() {
  return !/bot|crawler|spider|crawling/i.test(navigator.userAgent)
    && navigator.webdriver !== true;
}

Reference: GA4 data filters


Mistake #7: Firing the Purchase Event Without Deduplication

What it looks like: Your GA4 purchase events and revenue figures are significantly higher than your actual orders. You have a Shopify store where purchase fires 1.8x per transaction on average.

Why it happens: The order confirmation page can be:

  • Refreshed by the user (double submission)
  • Hit by the browser’s back button
  • Cached and re-served

Without deduplication, the purchase event fires every time the confirmation page loads — even for the same order.

How to fix:

Method 1: Transaction ID deduplication in GA4

GA4 automatically deduplicates purchase events with the same transaction_id within a 7-day window — but only if you’re consistently sending the transaction_id parameter.

Verify your purchase event includes it:

window.dataLayer.push({
  event: 'purchase',
  ecommerce: {
    transaction_id: 'ORDER-12345',  // ← This MUST be unique per order
    value: 59.99,
    currency: 'USD',
    items: [...]
  }
});

Method 2: sessionStorage flag

// On the confirmation page:
const orderId = 'ORDER-12345';
const key = `tracked_${orderId}`;

if (!sessionStorage.getItem(key)) {
  sessionStorage.setItem(key, '1');
  window.dataLayer.push({
    event: 'purchase',
    ecommerce: { transaction_id: orderId, ... }
  });
}

Method 3: GTM trigger with custom condition

In GTM, create a JavaScript variable that returns true only if the order ID hasn’t been tracked this session, then add it as a trigger condition on your purchase tag.

Reference: GA4 ecommerce measurement


Run a GTM Container Audit

Before your next campaign launch, run through this checklist:

□ Search page source for duplicate GTM containers or hardcoded GA tags
□ Preview mode: check each tag fires on the RIGHT pages only
□ Preview mode: no conversion tags fire on the homepage
□ All dataLayer variables return actual values (not undefined)
□ Cross-domain tracking configured if using multiple subdomains
□ Internal traffic filter active in GA4
□ Purchase event includes transaction_id
□ All tags are published (current container version is live)
□ Consent Mode v2 defaults set before any tags fire

When to Get Help

If your GA4 data doesn’t match your Shopify, Stripe, or CRM data by more than 15%, something is broken. The earlier you find it, the less historical data is poisoned.

We do GTM container audits as a standalone engagement — you get a documented list of every broken tag, variable, and trigger, with prioritised fixes. Book a free consultation to discuss your setup.

#gtm#google-tag-manager#analytics#debugging#data-layer#ga4

Want This Implemented Correctly?

Let our team apply these concepts to your specific setup — with QA validation and 30 days of support.