TRACKING SPECIALIST — BARIS ASA · LONDON
Synctag
Start the check → TRACKING SPECIALIST — BARIS ASA · LONDON
THE ARCHIVE · FAULT INDEX

The fault index

The same faults turn up across the archive. Each one is defined here once: what it looks like, why it happens, where it gets caught, and what putting it right involves. The cases, the intake check and the services all cite these codes.

← back to the homepage

F-1xx — Collection & duplication

Conversions miscounted at the source: fired twice, or double-attributed across browser and server.

F-101

Duplicate conversion firing

▮▮▮▮▯
Symptom
Purchases counted twice; revenue inflated on Meta and Google Ads, and in GA4 too once transaction_id goes missing. ROAS looks great, until finance disagrees.
Cause
The purchase tag fires more than once per order: a theme update double-injects it, a tag lives in both GTM and the platform, or a thank-you page reloads.
Found in
Tag Assistant / GA4 DebugView: two purchase events with the same transaction_id. Or GA4 revenue running ahead of the store's own figure.
The fix
Find every place the conversion fires, consolidate to one, and key it on transaction_id so a reload can't double-count.
F-102

Platform signals not deduplicated

▮▮▮▯▯
Symptom
Meta and Google report more conversions than actually happened. The browser hit and the server hit both claim the same sale.
Cause
Server-side conversions sent without the dedup key the platform needs: Meta CAPI and the Pixel firing without a shared event_id, or Google's server and browser conversions without a shared transaction_id, so the two hits are never recognised as one sale.
Found in
Meta Events Manager showing low or zero deduplication; conversion counts running above actual order counts.
The fix
Send the matching dedup key on both browser and server: event_id for Meta, transaction_id for Google, so each conversion is reconciled and counted once.
F-103

dataLayer timing & race conditions

▮▮▮▯▯
Symptom
Parameters there one day, missing the next: items arrays empty, values intermittently zero. The same tag passes in testing and fails for real users.
Cause
Tags fire before the dataLayer is populated. The tag races the push, or fires on page view while the ecommerce object arrives a beat later.
Found in
GTM Preview: variables resolving undefined on first fire; GA4 events arriving with missing parameters on a fraction of hits only.
The fix
Re-sequence the firing: trigger off the dataLayer push itself, not the page view, and verify every variable resolves before the tag ships.
F-104

Key events & counting mis-set

▮▮▮▮▯
Symptom
The event fires, but Google Ads optimises on the wrong number: conversions double-counted within a session, or never imported at all.
Cause
The event was never marked as a key event, or its counting method is wrong: "every" where it should be "once per session", or the reverse. Either way, Ads imports the wrong set.
Found in
GA4 Admin: the key-events list not matching what the business calls a conversion; the Ads conversion column disagreeing with GA4 for the same event.
The fix
Mark the right events as key events, set each counting method deliberately, and import the correct set into Google Ads.

F-2xx — Signal lost in transit

The event happened, but it never reached the platform intact. Gated by consent, or stripped on the way.

F-201

Consent Mode absent or mis-wired

▮▮▮▮▮
Symptom
EU/UK customers are buying, invisibly. A banner is installed, but conversions from consented users still don't show up.
Cause
The consent banner sits in front of the tags but Consent Mode v2 was never wired, or wired backwards. Tags either fire with no signal, or never fire at all.
Found in
Consent Mode debugging: default/update states missing or inverted; a visible gap between platform sales and tracked conversions in EU traffic.
The fix
Wire Consent Mode v2 correctly to the banner, with modelled recovery for non-consenting users where volumes allow it. Compliant, with no silent data loss.
F-204

Attribution lost in transit

▮▮▮▮▯
Symptom
Traffic that clearly drove sales piling up under "direct / none", or your own payment processor sitting in the top referrals. Real channels get no credit.
Cause
Campaign parameters or the Google click id (gclid) stripped by a redirect; a cross-domain step running without GA4's linker, so the session restarts; or a payment provider's return trip overwriting the original source.
Found in
A suspiciously large "direct" channel, or a checkout/payment domain showing up as a top referral; sessions arriving from ad platforms with no campaign attached.
The fix
Preserve UTMs and the gclid across redirects, configure cross-domain linking and the unwanted-referrals list, and stop the payment round-trip from overwriting the source.
F-205

Self-referrals & session fragmentation

▮▮▮▯▯
Symptom
Your own site sits in your referral report (shop.example.com "referring" www), and customer journeys snap in half at the subdomain hop.
Cause
Sessions restart at the domain boundary: the cookie isn't set at the root domain, or your own domains were never listed as unwanted referrals, so the second half of the journey credits the first half as its source.
Found in
Referral reports listing your own subdomains; landing pages that are mid-journey URLs; sessions running well ahead of users on multi-domain setups.
The fix
Set the cookie at the root domain, list your own domains as unwanted referrals, and verify one session survives the whole journey end to end.

F-3xx — Ecommerce & reconciliation

Funnel events partial or mismatched, and GA4 never agrees with the store platform.

F-301

Ecommerce events partial

▮▮▮▮▯
Symptom
Funnel blind spots: you can see purchases but not where shoppers drop off. GA4 never reconciles with the store platform.
Cause
Only some of the ecommerce events are implemented (purchase but not add_to_cart / begin_checkout), or the data layer is missing item-level detail.
Found in
GA4 ecommerce reports with gaps mid-funnel; item or revenue totals that don't match Shopify/Woo/the backend.
The fix
Implement the full ecommerce event set with a complete data layer, then reconcile GA4 against the platform row by row.
F-302

Conversion value inconsistent

▮▮▮▯▯
Symptom
Every platform reports a different revenue figure for the same orders: one includes shipping, one doesn't, one has its own currency idea. ROAS depends on who you ask.
Cause
Conversion value is built separately per destination: tax and shipping in one tag, out of another; currency left to default on one platform; discounts applied in some places and not others.
Found in
Row-by-row reconciliation: per-order values diverging by exactly the tax or shipping amount; currency mismatches in multi-market accounts.
The fix
Define value once (what's in, what's out, which currency) and feed every platform the same definition from one variable.

F-4xx — Server-side & match quality

Browser-only collection, with signal lost to ITP, blockers and poor match rates.

F-401

Server-side signals absent

▮▮▮▮▯
Symptom
Often 5–15% of conversions quietly missing, more where ad blockers run high. Match quality on Meta/Google is poor and ad platforms are optimising on thin data.
Cause
Collection is browser-only. Pixels blocked by ITP, ad blockers and short cookie lifetimes never reach the platform.
Found in
Low event match quality scores; a persistent gap between platform-reported and actual conversions even after consent is fixed.
The fix
Move collection server-side (sGTM), send first-party where it pays, and recover the match loss with CAPI / Enhanced Conversions.
F-402

Enhanced Conversions not configured

▮▮▮▯▯
Symptom
Lead campaigns optimising blind: match quality poor, the form-to-sale journey invisible, cost per lead climbing with no explanation.
Cause
Enhanced Conversions was never switched on, so no hashed first-party data goes back with the conversion and Google can't match it to the click. For lead-gen, offline closes never reach the platform at all.
Found in
Google Ads diagnostics: Enhanced Conversions "not active"; low match quality scores; lead events arriving with no user data attached.
The fix
Switch on Enhanced Conversions, and EC for Leads where the sale closes offline, sending hashed first-party data with consent in place.
F-403

GA4 ↔ Google Ads not linked

▮▮▮▯▯
Symptom
Ads optimises on its own pixel alone. GA4 conversions and audiences never reach it, and the remarketing lists sit empty.
Cause
The GA4–Google Ads link was never made, or made without conversion import and audience sharing, so the two accounts keep separate books on the same business.
Found in
GA4 Admin: product links empty; Ads showing no GA4-sourced conversions or audiences; remarketing audiences stuck at zero.
The fix
Link the accounts properly, import the right key events into Ads, and share audiences. One set of numbers on both sides.

F-5xx — Documentation & handover

Nothing written down, so every future change starts as archaeology.

F-501

Zero documentation

▮▮▮▮▮
Symptom
Nobody can say what fires, when, or why. Every future change, or staff handover, starts as archaeology.
Cause
The container grew by accretion: tags added under deadline, no naming, no record of what each one is for or what depends on it.
Found in
A container full of unnamed tags and triggers; no measurement plan; the previous setup's logic living only in someone's head.
The fix
Name and map the container, write a measurement plan, and hand over a record your team can change against next year.

F-6xx — Configuration & data integrity

Collected, but corrupted: unregistered dimensions, internal noise, and data that shouldn't be there at all.

F-601

Parameters sent, never registered

▮▮▮▮▯
Symptom
Reports full of "(not set)". The parameter is being sent on every event, the report just can't see it.
Cause
Event parameters pushed faithfully into the dataLayer and collected by GA4, but never registered as custom dimensions or metrics in admin. Collected, stored, invisible.
Found in
DebugView showing the parameter on every event while the standard report shows (not set); a custom-definitions list far shorter than the measurement plan.
The fix
Register every reporting parameter as a custom dimension or metric, scoped correctly, and retire the ones nobody reads.
F-602

Internal & bot traffic counted

▮▮▮▮▮
Symptom
Sessions look healthy until you realise a chunk of them are you: the office, the dev team, the agency, and a swarm of bots dressed as customers.
Cause
Internal-traffic filters never defined or left sitting in "testing"; staging and preview domains feeding the production property; known-bot exclusion assumed to catch what it doesn't.
Found in
Geography reports starring the office's city; conversion spikes that match deploy days; the hostname report listing staging URLs.
The fix
Define and activate internal-traffic filters, exclude dev and staging hostnames, and baseline how much of the "traffic" was never customers at all.
F-603

PII leaking into analytics

▮▮▯▯▯
Symptom
Email addresses sitting in your page paths and event parameters. A compliance problem first, and a Google policy strike waiting to happen.
Cause
Forms passing email or phone into the URL on submit; success pages carrying PII in query strings; tags forwarding all of it verbatim to every platform.
Found in
Page reports with @ in the URL; query parameters like ?email=; GA4's data-redaction settings untouched since setup.
The fix
Strip PII before it reaches the tags: clean the URLs at the source, switch on GA4's data redaction, and audit every parameter against what it's allowed to carry.

R-5xx — Reporting & dashboards

The numbers exist but nobody trusts them. Definitions disagree from one viewer to the next.

R-501

Reporting nobody trusts

▮▮▮▯▯
Symptom
Dashboards exist, but every meeting argues about whose number is right. The report gets opened once, then ignored.
Cause
No agreed definition per metric: "revenue", "conversions" and "sessions" mean different things in different tiles, pulled from sources that don't agree.
Found in
Two dashboards showing different totals for the same thing; metrics with no documented definition or owner.
The fix
Agree one definition per metric, build reporting on a single reconciled source, and label what each number means.
R-502

Sampling & thresholding unexplained

▮▮▯▯▯
Symptom
The same report shows different numbers on different days: totals shift, rows vanish, and nobody can say why.
Cause
Dashboard queries hitting GA4's API quotas and sampling; thresholding silently hiding rows where users could in theory be identified; nobody labelled where either applies.
Found in
The sampling icon nobody hovers over; rows that reappear when the date range shrinks; dashboard totals that disagree with the GA4 UI itself.
The fix
Design reports inside the quotas (fewer dimensions per chart, BigQuery export where it matters) and label where thresholding applies, so a missing row reads as policy, not error.

U-0xx — Unmeasured / no baseline

You can't say what is and isn't tracked. There's no ground truth to argue from.

U-001

Unmeasured, no baseline

▮▮▮▮▯
Symptom
You genuinely can't say what is and isn't tracked. Decisions get made on gut because there's no ground truth to point at.
Cause
No audit has ever been done. Tracking accreted over years and owners, and no one holds the full picture of what's live.
Found in
This is the starting state, not a single bug: the tracking audit exists to convert U-001 into a known list of specific faults.
The fix
Run a tracking audit: inventory what's firing, test it against reality, and produce the baseline every other fix is measured against.

Recognise two or more in your own setup? The intake check speaks the same codes, or open a case directly.