TL;DR
Most "GA4 events not showing" tickets on Magento 2 are not a tracking bug. They are a break at one of four points in a chain, and each point has a different tool that answers it. The mistake that costs the most time is starting at the end, in GA4 reports, where a missing event and a working-but-delayed event look identical. Start at the container instead. This article walks the chain in order and names the tool that answers each question.
Key Takeaways
- The GA4 extension generates a GTM container JSON that you import into your own container. Config changes require regenerating and reimporting it, and the container has to be published before anything reaches GA4 [1].
- The dataLayer preview window has an optional IP Address Restriction field: enter comma-separated IP ranges and only those addresses see the preview; left blank, there is no restriction [1].
- GTM preview mode answers a different question than DebugView. Preview tells you whether the tag fired; DebugView tells you whether Google received it [1][2].
- Server-side Measurement Protocol sends are verified from
ga4.logand the Debug Collect endpoint setting, both under the PRO Measurement Protocol configuration [1][3]. - The sales order grid carries a column marking which orders were sent by Measurement Protocol, which makes purchase verification an audit you can run over a date range rather than one order at a time [1].
- Consent state can be logged into
ga4.logalongside server-side events, which requires Measurement Protocol tracking and file logging both switched on [1]. - Content Security Policy is the most common environment-level cause after an upgrade. Magento 2.4.8 allows
region1.analytics.google.comwhen Google Analytics is enabled [5], and 2.4.9 made the GA module's CSP whitelist independent of the Adwords module [6].
Why do GA4 events go missing on Magento 2 in the first place?
Four things have to be true for an ecommerce event to appear in a GA4 report, and they fail independently.
The dataLayer push has to happen on the page. The GTM tag listening for it has to fire. The container holding that tag has to be the published version, not the draft you edited on Tuesday. And GA4 has to accept the hit and process it into the report you are looking at.
A merchant almost never reports it that way. What arrives is "add_to_cart stopped showing up," which is a statement about layer four and tells you nothing about layers one through three. So the first move is not to open GA4. It is to figure out which of the four links is broken, and each link has one tool that answers it cleanly.
One environment-level cause sits outside that model. Magento's Content Security Policy went to restrict mode on payment pages in 2.4.7 for PCI DSS 4.0 (other pages stay report-only), so a blocked script on the checkout page kills browser events at the source [4]. Magento 2.4.8 allowed region1.analytics.google.com when Google Analytics is enabled, the regional endpoint EU visitors get routed to [5], and 2.4.9 separated the Google Analytics module's CSP whitelist from the Adwords module's [6]. If events vanished on the day you upgraded, check the browser console for CSP violations first.
Start with the container, not the tag
The extension's client-side model is that it writes a dataLayer and generates a GTM container JSON, which you import into your own GTM container [1]. That generation step is where a lot of silent failures live, because the JSON reflects your configuration at the moment you exported it.
Change a setting in the extension and the container in GTM is now stale. The documented workflow is to regenerate the JSON from the export options and reimport it [1]. The same requirement applied in v1.12.1, when the dataLayer was refactored to match Google's recommendations and existing containers needed a reimport [1]. The symptom of an old container against a new dataLayer is a tag that never fires, because its trigger is watching for an event name the store no longer pushes.
Then there is publishing. An imported container sits in the workspace until you publish it [1]. You have probably got a GTM tab open somewhere right now with unpublished changes in it. This is the check that resolves the most "it worked in preview and not in production" reports, and it takes ten seconds.
Is the dataLayer firing? The preview window and its IP restriction
Layer one is answered inside Magento.
The extension includes a dataLayer preview window that renders the pushes on the page as they happen [1]. The setting that matters alongside it is the IP Address Restriction field, which is blank by default [1].
What you are checking here is narrow. Is the event name present, and in the snake_case form GA4 expects, since the extension's events follow Google's naming rather than the old Universal Analytics camelCase [1]. Are price and quantity numeric [1]. Is coupon an empty string when none applies [1]. Does the ecommerce object clear between pushes, which the extension does deliberately so values from one event do not bleed into the next [1].
Two size limits belong in the same check because they only bite on large pages. Item list impressions can be broken into chunks, with 15 the recommended size, and the extension documents 8KB payload support [1]. A category page with 96 products in the grid is not sending one push with 96 items in it.
For the list of what the extension pushes and when, our reference on which ecommerce events the GA4 extension tracks is the shorter read than the user guide.
Watching the tag fire: GTM preview mode
Layer two is Google Tag Manager's preview flow, and it answers one question: given this dataLayer push, did my tag fire [7].
Preview mode connects to your session and shows the sequence of events with the tags that fired on each and the tags that did not, plus the variable values at the moment of firing [7]. When a tag sits in the "not fired" list, the trigger condition is usually the problem, and the variable panel shows why within a few seconds.
A tag firing in preview means GTM executed it. It does not mean Google accepted the resulting hit. Those are different claims and they need different tools, which is the next section. If your server-side container is part of the picture, our walkthrough on previewing and debugging your GTM server-side container covers the equivalent flow there.
Is GA4 receiving it? DebugView and its blind spots
DebugView is the last browser-side link. It shows the event stream for sessions flagged as debug sessions, with parameters, in close to real time [2].
Use it to confirm three things: the event arrived, the parameters arrived with it, and the values match what the dataLayer had. Parameter loss between the tag and GA4 is the failure DebugView catches that nothing upstream does, and it is usually a mapping problem in the tag rather than anything in Magento.
DebugView is also where custom dimension work gets checked. The extension supports custom dimensions in the dataLayer [1], and as of v1.17.2 it carries a safeguard against writing to GA4's reserved field names [1]. That safeguard matters because a custom dimension named after a reserved field could replace the real value in the event payload, which showed up as errors during cart events [1].
Two blind spots. DebugView only shows sessions in debug mode, so an absence there says nothing about your normal traffic. And standard GA4 reports are processed on a delay, which means an event visible in DebugView and missing from a report is often a processing question rather than a tracking one. Check the realtime report before you conclude anything, and if you want the equivalent view for server-side data, we covered monitoring realtime server-side data in GA4 separately.
Google announced another Google tag and Tag Manager consolidation wave on August 20, 2026, with interface changes across both products [8]. If a menu name in a tutorial does not match what you see, that is why.
Verifying the server-side half: ga4.log, the debug endpoint, and the order grid
Measurement Protocol is the extension's server-side route in PRO, enabled at Admin > WeltPixel > GA4 PRO > Enable Measurement Protocol Tracking Configuration [1]. None of the browser tools see it. It leaves your server directly, so it needs its own three checks.
The file log. Switch on file logging and sends are written to ga4.log [1]. This is the artifact that separates "nothing was sent" from "something was sent and rejected," which is the fork the whole investigation turns on.
The Debug Collect endpoint. The same configuration block has a Debug Collect option, which points sends at Google's debug collection endpoint instead of the live one. Google's debug endpoint validates the payload and returns messages describing what is wrong with it, rather than failing silently the way the production endpoint does [3]. Events sent to the validation server don't show up in reports, so switch Debug Collect off when you finish [3].
The order grid column. The sales order grid carries a column marking which orders were sent by Measurement Protocol [1]. This is the check that scales. Instead of testing one order, filter the grid across last month and look for the gaps, then work out what the gapped orders have in common.
Usually they have order status in common. The extension supports excluding orders in specified statuses from server-side tracking, with a cron job that pushes an order once it moves out of an excluded status [1]. An order that sat in a held status when it was placed and was never re-pushed looks exactly like a tracking failure in the grid, and is not one. Our older write-up on fixing events not tracked when using Measurement Protocol covers a different cause entirely: a GA4 property setting that silently drops Measurement Protocol events carrying a User ID. If the symptom is revenue that does not reconcile, missing transactions and revenue in GA4 is the closer match.
Two settings shape what you see in the logs. Consent state is logged alongside server-side events [1], so the log tells you what the consent signal was at the time of the send. And Client ID Fallback supplies a client identifier for Measurement Protocol events through gtag.js so sends keep a stable identity when cookies are unavailable [1].
What each tool cannot tell you
Every tool above answers one question and is silent on the rest. Written out, the boundaries are the actual method.
| Tool | Answers | Silent on |
|---|---|---|
| dataLayer preview window | Did the page push the event, with which fields | Whether any tag consumed it |
| GTM preview mode | Did the tag fire, with which variable values | Whether Google accepted the hit |
| GA4 DebugView | Did GA4 receive the event and its parameters | Everything outside debug sessions; report processing |
ga4.log |
Did the server send, and what came back | Anything browser-side |
| Debug Collect endpoint | Is the Measurement Protocol payload valid | The validation server does not validate the api_secret or firebase_app_id [3] |
| Order grid MP column | Which orders were sent server-side | Why a gapped order was skipped |
Two things stay genuinely unresolved by this toolset, and pretending otherwise wastes people's afternoons.
The first is duplication when you run both halves. The extension's approach is to pause the corresponding GTM tags for events you also send by Measurement Protocol, or to use the setting that automatically disables the dataLayer for enabled Measurement Protocol events [1]. The main WP - GA4 tag is not one to pause [1]. Verifying the outcome means comparing counts in GA4 over a window, because no tool here reports a deduplication status.
The second is the gap you cannot close. Some events never happen because a visitor declined consent or a blocker stopped the browser half, and I am not going to print a recovery percentage for that, because we do not publish one and the numbers that circulate come from individual samples. What the toolset gives you is the ability to say the pipeline is intact, which is a smaller claim than "the numbers are complete" and the only one the evidence supports.
FAQ
Why can I see the dataLayer preview on my machine but nobody else can?
Because someone entered your IP range in the extension's IP Address Restriction field [1]. Colleagues on a different network, or on mobile data, will not see the preview until their address is on the list.
I changed a setting in the extension and events stopped matching. What did I miss?
The GTM container JSON regeneration and reimport. The generated container reflects your configuration at export time, so a config change requires exporting the JSON again and importing it into GTM, then publishing the container [1]. This also applied to the v1.12.1 dataLayer refactor, which required a reimport for existing installs [1].
How do I verify purchases that were sent server-side rather than in the browser?
Use the Measurement Protocol column in the sales order grid to see which orders were sent [1], and check ga4.log for the send and the response [1]. Orders in an excluded status are pushed later by cron once they leave that status, so a gap in the grid is not automatically a failure [1].
Which Magento and PHP versions does this apply to?
As of GA4 v1.17.3, released August 3, 2026, the documented compatibility range is Magento 2.3.0 through 2.4.9, with PHP 8.5 supported since v1.17.0 [1]. Installation has been Composer-only since v1.16.0, so any walkthrough that has you copying files into app/code is describing a method we stopped supporting in January 2026 [1].
If you want the dataLayer preview, the generated container, the ga4.log file, and the order grid column in one place rather than assembled from separate tools, that is the Google Analytics 4 PRO extension with server-side tracking for Magento 2.
Sources
- WeltPixel Google Analytics 4 extension for Magento 2, user guide and changelog, cited as of v1.17.3. https://docs.weltpixel.com/GA4/User-Guide-WeltPixel-Google-Analytics-4.html
- Google Analytics Help, "DebugView: monitor your data collection in real time." https://support.google.com/analytics/answer/7201382
- Google Analytics for Developers, Measurement Protocol validation and the debug endpoint. https://developers.google.com/analytics/devguides/collection/protocol/ga4/validating-events
- Adobe Experience League, Adobe Commerce 2.4.7 release notes. https://experienceleague.adobe.com/en/docs/commerce-operations/release/notes/adobe-commerce/2-4-7
- Adobe Experience League, Adobe Commerce 2.4.8 release notes. https://experienceleague.adobe.com/en/docs/commerce-operations/release/notes/adobe-commerce/2-4-8
- Adobe Experience League, Adobe Commerce 2.4.9 release notes. https://experienceleague.adobe.com/en/docs/commerce-operations/release/notes/adobe-commerce/2-4-9
- Tag Manager Help, "Preview and debug containers." https://support.google.com/tagmanager/answer/6107056
- Tag Manager Help, Google tag and Google Tag Manager consolidation announcement. https://support.google.com/tagmanager/answer/17079602