Most tracking problems are not mysterious. They fall into a handful of categories, and each one shows up in a specific tool. This guide gives the order I check things in, what each tool tells you, and the root causes behind nine out of ten tickets.
The Tools and What Each One Proves
| Tool | Proves | Does not prove |
|---|---|---|
| GTM Preview | Which triggers fired, which tags fired, variable values, dataLayer state | That the request reached the platform |
| Tag Assistant companion | Google tags detected on the page, consent state | Non-Google tags |
| Tag debugger extension such as Insighter Debugger | Actual network requests to GA4, Google Ads, Meta, TikTok with parameters | Whether the platform accepted them |
| Browser network tab | Every request, status codes, payloads | Easy readability |
| GA4 DebugView | Events received by GA4 with parameters and user properties | Why an event is missing |
| Meta Test Events | Events received by Meta, parameters, matched keys, deduplication | Browser-side cause |
| Google Ads Diagnostics | Conversion tag status, Enhanced Conversions status, Consent Mode status | Anything in real time |
The Method
Step 1: Reproduce in Preview
Open GTM Preview, connect to the page, and perform the action. In the left column, find the event that should have triggered the tag. If it is not there, the problem is upstream: the dataLayer push never happened, the click trigger's conditions do not match, or the page navigated before GTM saw it.
Step 2: Check the trigger
Click the event, open the tag that should have fired, and look at Firing Triggers. Each condition shows a tick or a cross. A cross tells you exactly which condition failed and what value it saw. Fix the condition or the data.
Step 3: Check the variables
Open the Variables tab for that event. Every value the tag sends should be populated. Undefined means the Data Layer Variable name does not match the push, the push came later, or the key is nested deeper than the variable path.
Step 4: Check consent
Open the Consent tab for the event. If ad_storage or analytics_storage shows denied, tags with consent requirements will not fire, and Google tags in Advanced mode will send only cookieless pings. Confirm the consent platform fired on Consent Initialization and that accepting the banner updates the signals.
Step 5: Check the request left the browser
Preview says fired; now prove it. Open a tag debugger such as the Insighter Debugger extension and look for the request to the platform: the GA4 collect request with the event name and parameters, the Google Ads conversion request with the label, the Meta request with the event name and custom data. If the request is missing, an ad blocker, a browser privacy setting or a JavaScript error after the tag fired is the usual cause. If it is there with the wrong data, the mapping in the tag is wrong.
Step 6: Check the platform received it
GA4 DebugView for GA4, Test Events for Meta, Diagnostics for Google Ads after a day. If the request left with the right data and the platform shows nothing, check the destination ID, the property's data filters, and for GA4 whether your traffic is being excluded as internal.
Step 7: Server-side, if present
Open the server container Preview. Confirm the incoming request, the client that claimed it, the parsed event data, and each outgoing request with its response code. A 200 from the vendor means it was accepted.
Root Causes, Most Common First
- Trigger condition typo or wrong operator. Equals versus contains, a trailing slash, mixed case.
- dataLayer push after the tag fired, or never. Check the push order in the Data Layer tab.
- Consent denied by default and never updated. Consent platform not on Consent Initialization.
- Ad blocker on the testing browser. Test in a clean profile.
- Page navigated before the request sent. Use Just Links for links, or delay the redirect.
- Duplicate source. A plugin, channel app or hard-coded snippet in addition to GTM.
- Wrong ID. Old measurement ID, conversion label from a different action, pixel from another business.
- Variable path wrong for nested data.
ecommerce.items.0.item_id, notitems.item_id. - Element selector too narrow. Click on the icon inside the button did not match.
- Published version differs from the workspace. The fix exists in a workspace nobody published.
Debugging Duplicates
In Preview, count fires per event. If one, use the tag debugger to count requests to the platform. Two requests with one GTM fire means another source. Search the page source for the platform's script domain, check plugins and channel apps, and check for a second GTM container.
Debugging Missing Values
Values that arrive as zero or empty are usually format problems: a string with a currency symbol, a value read before the API response populated it, or a Shopify amount in cents. Log the dataLayer in the console at the moment of the event to see what the site actually pushed.
Debugging Attribution
The conversion arrives but with no campaign: Conversion Linker missing, cross-domain not configured, or the conversion happened on another domain without linking. Arrive with a test gclid and watch the _gcl_aw cookie and the linker parameter on cross-domain links.
A Testing Checklist to Run Before Publishing
- Each conversion fires once per real action.
- Nothing fires on failed or incomplete actions.
- Values and currencies are correct numbers.
- Consent blocks what it should and releases on acceptance.
- Requests reach each platform with the expected parameters.
- Admin pages fire nothing.
- The version note says what changed.
Outcome
A fixed order of checks that turns "tracking is broken" into a specific cause in minutes, and a habit of proving each layer, from trigger to platform, rather than guessing.
