← Guides

fig. stream
Google Analytics 4

How to find broken GA4 events and missing properties

Trace one GA4 event from the business action to the report to find where it breaks: the dataLayer, GTM, the hit, DebugView, or reporting.

Mariona MartíDigital Marketing Specialist
14 min read · 3155 words

The most reliable way to find broken GA4 events and missing properties is to trace one expected event through the collection path: confirm the business action, inspect the dataLayer, check the tag or gtag() call, inspect the browser request, and verify the result in GA4 DebugView and in reports. The sequence tells you whether the failure happened before GA4 received anything, in the payload, or after collection, in reporting. Use DebugView for a focused test, then add production monitoring if the issue could affect visitors you didn’t reproduce yourself.

The key distinction is between collection and reporting. An event can be missing because it never fired. It can also arrive with the wrong name or an incomplete payload. And teams often say “property” for an event parameter, while GA4 user properties are a separate, user-level concept. A custom event parameter can be collected correctly and still be missing from standard reports until you register it as a custom dimension or metric.

Start with the layer where the evidence disappears

Don’t start by changing the GA4 report. First find the last layer where the expected event or property is still present.

What you observeWhat it usually meansEvidence to collectFirst place to fix
The user completes the action, but the event is not in the dataLayer or the gtag() callThe application logic, form callback, state change, or business trigger didn’t produce the eventThe user action, console output, dataLayer state, and releaseSite or app implementation
The event is in the dataLayer, but the GA4 tag doesn’t fireThe GTM trigger, event name, variable, consent condition, or tag sequencing doesn’t match the dataGTM Preview timeline, trigger conditions, variables, and consent stateGTM container
The tag fires, but there is no GA4 requestTag configuration, Measurement ID, consent behavior, the browser, or the transport is blocking collectionGTM tag result and the browser’s Network panelTag configuration, consent setup, or browser path
The request exists, but a property is missing or wrongThe mapping, variable, object shape, field name, or type is wrongThe request payload and the source dataLayer objectData mapping or implementation
DebugView shows the event and property, but a report doesn’tThe parameter isn’t registered for reporting, or the report has processing or scope limitsDebugView event details, custom definitions, report scope, and processing timeGA4 reporting configuration
The event appears twiceTwo triggers, two tags, automatic collection, retries, or client and server paths measure one action twiceGTM timeline, request timestamps, event identifiers, and implementation pathsTrigger or deduplication logic
The event works on the test device but disappears for some visitorsConsent, ad blockers, browser restrictions, devices, geography, or an untested route change the resultRequests grouped by consent state, browser, device, route, and releaseCoverage, consent, or production implementation

The table is a triage map, not a substitute for reading the payload. A tag that fires is not proof that GA4 received the right event, and an event in DebugView is not proof that every visitor sent it. The first rows are what you check by hand; the last row is where Trackingplan, a digital analytics agent, works: on the hits real traffic sends, per event, per property, and per platform.

Define the expected event before debugging it

Write down what the event should contain before you look at what it actually contains. Keep the specification short enough that a developer, an analyst, and a QA reviewer can share it.

For each event, record:

Use Google’s recommended event names and parameters when one fits. Google recommends generate_lead when a user submits a form or a request for information, add_to_cart when a user adds items to a cart, and purchase when a user completes a purchase. The recommended name and its parameters give GA4 more context for reports.

The specification also prevents a common mistake: treating a missing property as a missing event. These are different findings:

Expected event: generate_lead
Observed event: generate_lead
Missing field:  form_id

Here the collection path works. The property mapping doesn’t.

Follow the diagnostic sequence

1. Confirm the real business action

Start with the action that should create the event, not the button that seems to represent it.

For a lead form, success is a confirmed server response or a thank-you state; a click on submit is only an attempt. For a purchase, success is a confirmed transaction, not a click on “Pay.” For add to cart, confirm that the cart accepted the item.

A click trigger can fire when validation fails, the request is rejected, or the user leaves before the action completes. If the action never reaches the application state that should produce the event, GA4 is not the first layer to repair.

Check:

  1. Reproduce the action in a clean session.
  2. Confirm the application reports success.
  3. Inspect the dataLayer push or gtag() call at that moment.
  4. Compare the observed event name and fields with the specification.

In a GTM setup, a deliberate dataLayer event pushed after the success state is easier to debug than a broad click listener.

2. Use GTM Preview to inspect triggers and variables

If Google Tag Manager is in the path, use Preview and Tag Assistant before touching GA4. Google’s Preview and debug documentation describes browsing the site as if the container draft were live, then inspecting which tags fired, in which order, and with which data.

For the event under test, check:

Typical findings at this layer:

If the tag doesn’t fire, stay in GTM until you can explain why. DebugView can’t help with a request GTM never tried to send.

3. Inspect the raw browser request

GTM Preview shows what the container did. The Network panel shows what the browser actually tried to send.

Open Chrome DevTools before you reproduce the action, then use the Network panel to inspect the request: headers, payload, initiator, timing, and cookies. Filter for the GA4 collection request and compare it with the event you expected.

Verify that:

This step separates a trigger problem from a destination problem:

GTM resultBrowser requestDiagnosis
Tag didn’t fireNo requestTrigger, consent, sequencing, or tag configuration
Tag firedNo requestBrowser blocking, transport, consent, or tag configuration
Tag firedRequest with incomplete fieldsMapping or source data
Tag firedRequest with the right fieldsMove on to DebugView and reporting

Don’t infer that the payload is right from the GTM interface. The browser request is the evidence of what left the page.

4. Verify receipt in GA4 DebugView

DebugView shows the events and user properties GA4 collects from a selected device in real time, and it needs debug mode. On a test device, Tag Assistant or GTM Preview turns it on. Then open Admin › Data display › DebugView and reproduce the action.

Select the event and inspect:

An empty DebugView doesn’t mean the event is absent from all GA4 traffic. Check the debug signal, the selected device, privacy controls, the consent state, and the browser request. Google notes that client-side privacy controls and Consent Mode without the required consent can keep events out of DebugView.

DebugView is built for a focused implementation test, not for a historical audit of every visitor. Save the request or your test notes when you need a lasting record.

5. Separate collection from reporting

If DebugView shows the parameter but a standard report doesn’t, collection may already be working.

Google’s event-parameter guidance is explicit: sending a custom parameter is only the first step. To use it in standard reports and explorations, register it as a custom dimension or metric. A newly registered definition can take time to show up in reports.

Check:

  1. Is the parameter visible in DebugView?
  2. Is it an event parameter or an item-scoped ecommerce parameter?
  3. Is the custom dimension or metric registered with the right scope?
  4. Does the report use the same event and parameter?
  5. Has enough processing time passed?
  6. Is the report filtered by another stream, date range, or audience?

Don’t change the tag to fix a correct payload when the gap is in the reporting configuration.

Use the last confirmed evidence to choose the fix

Once you have checked the five layers, the last piece of evidence that holds tells you what to fix.

Last confirmed evidenceWhat to compare nextLikely fix
The business action succeeds, but no event is createdApplication callback, event listener, and dataLayer pushEmit the event from the confirmed success state
The event is in the dataLayer, but the tag is absent from GTM PreviewTrigger event name, trigger filters, tag sequencing, and consent conditionsCorrect the trigger or variable mapping
The tag fires, but there is no requestMeasurement ID, tag configuration, browser errors, blocking, and consentRepair the transport or the consent configuration
The request exists, but a field is missingSource object, GTM variable, key spelling, nesting, and typeCorrect the mapping or the source payload
The request is right, but DebugView is emptyDebug mode, selected device, consent, privacy controls, and GA4 propertyFix the test setup or the destination configuration
DebugView is right, but the report is wrongCustom definitions, scope, filters, processing delay, and dimensionsRegister or correct the reporting definition
One action creates several requestsClient triggers, enhanced measurement, server-side forwarding, retries, and identifiersRemove the duplicate path or deduplicate

The goal is not for every layer to look healthy on its own. It is to connect one business action to one expected event with one valid payload.

Check the events that carry revenue and leads

purchase needs transaction and revenue evidence

Check the transaction identity, the revenue fields, the currency, and the items array together. Google’s ecommerce guidance shows transaction_id, value, currency, and items in the purchase payload, and currency is required when value is set.

gtag("event", "purchase", {
  transaction_id: "T_12345",
  value: 72.06,
  currency: "USD",
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Blue Widget",
      price: 24.02,
      quantity: 3
    }
  ]
});

Check that:

If purchase appears in DebugView but revenue is wrong, inspect the raw request and the ecommerce object before changing report settings. A purchase with the wrong value is a payload problem, even when the event count looks healthy.

add_to_cart needs item-level context

Google’s ecommerce documentation uses add_to_cart with currency, value, and an items array. Each item needs at least item_id or item_name, and both are recommended. If you send value, send currency.

gtag("event", "add_to_cart", {
  currency: "USD",
  value: 24.02,
  items: [
    {
      item_id: "SKU_12345",
      item_name: "Blue Widget",
      price: 24.02,
      quantity: 1
    }
  ]
});

When the event count is there but product reports are empty, inspect the nested items structure. An item_id inside an item object is not a top-level event parameter. The tag can fire while the ecommerce payload stays unusable.

generate_lead needs a confirmed submission

Google recommends generate_lead when a user submits a form or a request for information, with value, currency when value is set, and an optional lead_source. Teams often add context such as form_id, form_location, or lead_type. Useful, but no substitute for a reliable success trigger: send the event after the submission succeeds, not when the button is clicked, and register the custom fields you analyze every week.

Diagnose each failure class

Missing event

Trace it in this order:

  1. Did the business action succeed?
  2. Did the application emit the expected dataLayer event or gtag() call?
  3. Did GTM match the trigger and fire the tag?
  4. Did the browser send the GA4 request?
  5. Did the request go to the intended property?
  6. Did DebugView receive the event?

The first “no” is the layer to investigate.

Missing property

If the event exists, compare the property at three points:

If it disappears between the first and second point, fix the variable path or the object shape. Between the second and third, inspect the tag configuration, the parameter mapping, and how the request is built. If it is in the request and in DebugView but not in reports, check custom definitions and scope.

Wrong type

A value can be present and still be wrong. Compare the expected type with the request:

Don’t normalize a wrong value in the report. Fix it at the source or in the mapping.

Duplicate event

A duplicate needs an inventory of every path that can send the action:

Compare timestamps, initiators, transaction IDs, and releases. A duplicate purchase is a revenue problem even when each copy is valid on its own.

Repeat the same test in each relevant consent state. A page can work in a consented DebugView session and still suppress collection for visitors who haven’t granted consent. Record the consent state next to the event evidence; otherwise “the tag didn’t fire” is an incomplete finding that can send the team to the wrong fix. The Consent Mode in GA4 guide covers the setup.

Add coverage beyond one DebugView session

DebugView answers one question well: what did this test device send right now? It doesn’t answer what production sent.

You need a wider check to catch:

For a small implementation, a versioned specification plus release checks, request inspection, and a periodic report review can be enough. When the business depends on many events, properties, destinations, or routes, monitoring real traffic adds evidence that a controlled session can’t.

That is the gap Trackingplan covers. One tag, SDK, or server-side hook, with no schema to define and no rules to write: it learns your baseline from real traffic and compares every hour against it, per event, per property, and per platform. Missing properties, dead tags, duplicate fires, broken triggers, type mismatches, and vendors firing before opt-in are caught on real traffic and posted with an explanation and links to the affected hits. It only observes the data your site or app already sends. The GA4 monitoring guide explains how rules, anomalies, and reconciliation fit together.

It doesn’t replace GTM Preview for an unpublished container or DebugView for a focused receipt check. Each tool proves a different part of the path.

The checklist for the next investigation

FAQ

Why does my GA4 event appear in GTM Preview but not in GA4?

GTM Preview proves that the container fired a tag. It doesn’t prove that the browser sent a valid request or that GA4 received it. Inspect the Network panel for the collection request, then check the Measurement ID, the consent state, browser blocking, and the DebugView setup.

Why is a GA4 parameter visible in DebugView but missing from reports?

A custom parameter can be collected without being available as a report dimension or metric. Register it as a custom dimension or metric with the right scope, then allow time for it to appear. Also check that the report uses the same event and date range.

How can I find duplicate GA4 purchases?

Inspect every client, server, page-load, callback, and retry path that can send purchase. Compare request timestamps, initiators, transaction IDs, GTM firing history, and the order confirmation flow. A thank-you page that can be refreshed and client plus server forwarding are the usual suspects.

Can DebugView prove that all visitors are tracked correctly?

No. DebugView validates one debug device over a recent window. It is the right tool for focused testing, but it doesn’t cover every browser, device, route, consent state, app version, or release. Add release checks or real-traffic monitoring when those conditions matter.

Stop where the evidence diverges

The fastest reliable sequence is business action → dataLayer or gtag() → GTM Preview → browser request → DebugView → reporting configuration. Stop at the first layer where the evidence diverges from the specification, fix the cause there, and rerun the same test: by hand on one device, and with Trackingplan on the traffic you can’t reproduce. For broader GA4 problems, the GA4 troubleshooting guide and the event tracking guide cover setup and governance.

Mariona MartíDigital Marketing Specialist

Digital Marketing Specialist

Trackingplan

See everything. Miss nothing.

Your implementations audited around the clock with real-time, real-user data. Real-time alerts about errors or changes in your data, campaigns, pixels, privacy and consent. Let AI flag issues before they cost you.