How to Fix GA4 (not set) Source/Medium & Unassigned Traffic

 

Lately, we've been asked to investigate a lot setups where major portion of the traffic is not being assigned to any source/medium.

 

What Unassigned means?

In Google Analytics 4, Unassigned traffic means GA4 successfully recorded the user’s visit, but it could not match the event’s traffic source parameters to any rule in its Default Channel Grouping.

Unlike (not set) - which usually means a parameter was entirely missing, unassigned traffic means GA4 did get source/medium data, but it didn't fit into GA4's pre-defined categories (like Paid Search, Organic Social, Direct, or Email).

GA4 uses strict, rule-based logic to categorize incoming traffic based on utm_source, utm_medium, and utm_campaign. If those parameters fall outside GA4's recognized syntax, or if critical session events fire out of order, the traffic gets dumped into the Unassigned bucket.

 

What (not set) means?

In Google Analytics 4, (not set) is a system placeholder that means GA4 failed to receive or process information for a specific dimension. In terms of dimensions, this could mean: 

  • 1. Session source / medium = (not set) - GA4 recorded a session, but it could not determine how the user arrived on the site.
  • 2. Landing page = (not set) - A session took place, but GA4 never registered an initial page load for that session.
  • Custom Dimensions = (not set)  - You registered a Custom Dimension in GA4 Admin (e.g., user_type or author_name), but the incoming event didn't contain that event parameter.

 

Why this happens?

A sudden increase in unassigned, (not set), or (direct) / (none) transactions across multiple clients using GTM and GA4 usually stems from broken session continuity, tag execution timing, or payment gateway redirects.

 

Missing Unwanted Referral Exclusions (Payment Gateways)

Cause:

When a customer is redirected to an external payment provider (e.g., PayPal, Stripe, Klarna, regional gateways) and returned to the order confirmation page:

  • If the payment domain isn't in GA4's Unwanted Referrals list, GA4 treats the return visit as a new session driven by the payment processor as a referrer.
  • If referral headers get stripped during HTTPS/HTTP cross-domain redirects, GA4 falls back to (direct) / (none) for the purchase event.

Fix: 

  • In GA4: Admin > Data Streams > [Web Stream] > Configure Tag Settings > List Unwanted Referrals. Add all third-party payment gateway domains (e.g., paypal.com, checkout.stripe.com).

 

Consent Mode v2 & Tag Firing Order Race Conditions

Cause:

GA4 event tags (like purchase or page_view) fire on early triggers before the main Google Tag updates the consent state or initializes the session. If an event tag fires without a valid session context established by the Google Tag, GA4 records the purchase without session attribution parameters, resulting in (not set) or Unassigned.

Fix: 

  • Ensure the Google Tag fires on Consent Initialization - All Pages or Initialization - All Pages.
  • Verify that purchase and other GA4 event tags fire after consent is granted, or use a Trigger Group pairing the purchase trigger with the consent update event.

 

Server-Side GTM (sGTM) Mismatches & Dual Initialization

This applies for clients that are using sGTM (Server-Side Google Tag Manager)

Cause: 

Web tags use the browser's _ga cookie, while server-side events rely on FPID. If some web requests bypass the server endpoint while others go through sGTM, GA4 treats them as two completely separate users, stripping the original acquisition source from the server-fired purchase.

Also third-party app plugins or hardcoded gtag() snippets on the thank-you page can re-initialize GA4 without the server_container_url parameter, severing session continuity.

Fix: 

Inspect the browser Network tab on the thank-you page:

  • Filter for v=2 or your GA4 Measurement ID.
  • Ensure all requests route exclusively to your sGTM custom domain (or web endpoint) and that no native client scripts fire secondary calls to google-analytics.com.

 

Measurement Protocol Purchases Without session_id

Cause:

If purchase events are pushed directly from the client's backend via the GA4 Measurement Protocol, sending a purchase with only client_id creates an unattached event. GA4 requires both a valid client_id and the active session_id (retrieved from the user's _ga_<container-id> cookie at checkout) to bind the purchase to the active session.

If sent >72 hours late or missing timestamp_micros, GA4 drops session correlation, dumping the revenue into (not set).

Fix:

  • Capture session_id from the client cookie during checkout and pass it explicitly in the Measurement Protocol payload alongside client_id and engagement_time_msec. If you're using our Google Tag Manager GA4 extension for Magento 2, this is natively handled by the extension.

 

Cross-Domain Tracking Breakdown

Cause:

If the checkout spans across domains or subdomains (e.g., store on brand.com and checkout on checkout.brand.com or a hosted platform), cross-domain linking (_gl URL parameter) is missing or broken on the transition link/form submit, GA4 loses the original _ga cookie and session context.

When the user completes the purchase, GA4 starts a brand-new session on the destination domain, marking the source as (direct) or the landing domain.

Fix:

  1. Configure cross-domain domains under GA4 Data Stream > Configure Tag Settings > Configure Your Domains. Ensure links and forms passing users to checkout maintain the _gl URL query string.

 

Gooogle Tag Manager Tag Sequencing

Cause:

Tags firing before the core Google Tag (the base configuration tag) is one of the single most common reasons e-commerce stores and websites see transactions or events end up as (not set), (direct), or Unassigned.

The Google Tag is the Initializer - when a user visits a page, the Google Tag is responsible for reading the incoming URL query parameters (utm_*, gclid, gbraid), inspecting the browser's HTTP Referer header, writing/updating the GA4 session cookie (_ga_<CONTAINER_ID>), and generating the session_id parameter.

It binds all that marketing source context (e.g., google / cpc or newsletter / email) to that specific session_id. If a custom GTM event tag such as a purchase, add_to_cart, or custom dataLayer event, fires before the Google Tag has executed:

Missing Session Context: The event arrives at Google Analytics servers without an active session_id or session attribution context because the cookie and parameters haven't been processed yet.

  • Orphaned Hits: GA4 receives the purchase payload (items, value, transaction_id), but it has no session container to attach it to.
  • Data Loss / Unassigned: GA4 registers the event, but because it lacks the campaign details that the Google Tag was supposed to extract from the landing URL or referrer, it falls back to:

    Session source / medium = (not set)
    Default channel group = Unassigned

Fix:

  1. Set your Google Tag trigger to Consent Initialization - All Pages or Initialization - All Pages.
  2. Never trigger page-load events on Initialization. Trigger event tags on Container Loaded (Page View), DOM Ready, or custom dataLayer events.
  3. In the purchase tag's Advanced Settings > Tag Sequencing, check "Fire a tag before this tag fires" and select your Google Tag.

 

Inconsistent server_container_url for sGTM implementations

Cause:

If you're using sGTM (Server-Side GTM), usually Google Tag receives a parameter called server_container_url, this tells the tag where to send data to. By default, all other tags should inherit this setting, but we have observed that on few occasions tags are not automatically using the same server_container_url and this results in some events being sent directly to GA4 causing the (not set) issue. This can also happen if you have hard-coded GA4 implementation on the site or another GTM snippet running in parallel that sends data directly to GA4.

Fix:

  • Create a resusable configiration variable in GTM and set server_container_url explicitly in evey tag

 

 

Google Analytics 4 Audiences

Cause:

GA4 Audiences specifically "Audience Triggers" can cause Unassigned traffic and (not set) attribution in your reports. Unlike a standard GTM event triggered directly by a user clicking a button or loading a page, Audience Trigger events are evaluated and generated on Google’s backend processing servers. 

When a user meets the criteria for an audience, Google's backend fires the generated event asynchronously.

Because this event is generated on the server side rather than directly within the active web session's page context, it often lacks a live session_id or page_view binding at the exact millisecond of creation.

Fix:

  • Avoid using these at all costs

 

AI traffic 

Traffic originating from AI suggestions, LLM answers, and AI search engines (like ChatGPT, Perplexity, Claude, Gemini, and Google AI Overviews) is one of the biggest drivers of unassigned and misclassified traffic in GA4 today.

While real users click links embedded in AI answers, GA4 frequently measures this traffic inaccurately or strips its attribution entirely.

 

Why AI Suggestions can potentially cause traffic measurement Issues?

 

1. Stripped Referrer Headers (App-to-Web Transitions)
When users click a link inside mobile apps (e.g., ChatGPT app, Copilot app, or embedded webviews inside Perplexity), the application often strips the HTTP Referer header for privacy or technical reasons.

The Result: GA4 receives the hit with zero source context, dumping the session straight into (direct) / (none) or (not set).

 

2. Lack of Dynamic UTM Tagging
Unlike email newsletters or paid ads, links cited dynamically inside generative AI outputs do not append utm_source, utm_medium, or campaign parameters. Without UTM parameters, GA4 is forced to rely solely on browser referrer strings.

 

3. Rule Mismatches in GA4 Channel Grouping
When AI referral domains do pass through cleanly (e.g., chatgpt.com, perplexity.ai, or claude.ai), GA4’s default channel definitions historically didn't have explicit rules for AI platforms. Depending on the property configuration:

They land in generic Referral.

If combined with custom parameters or non-standard protocols, they get dropped into Unassigned.

 

4. Masked Google AI Overview Traffic
When users click links inside Google’s AI Overviews (SGE) directly on the Search Results Page:

Google sends the traffic under standard google / organic referral headers.

GA4 blends this traffic into standard organic search, making it impossible to separate traditional "blue link" clicks from AI-driven answer clicks without explicit parameter tracking.

 

How to Fix and Accurately Track AI Traffic in GA4

You can reclaim visibility by configuring a Custom Channel Group in GA4 specifically for AI referral traffic.

Step-by-step Setup:

  • Go to GA4 Admin > Data Display > Channel Groups.
  • Select Copy to Create New (based on your Default Channel Group).
  • Click Add New Channel and name it AI Search / Assistants.
  • Set the condition rule to Source matches Regex: .*(chatgpt|openai|perplexity|claude|gemini|copilot|poe|phind).*
  • Reorder the channel list: Drag your new AI Search channel above the generic Referral and Unassigned rules so GA4 matches AI traffic first.

 

Quick Start Guide & How to

Please find below a useful tips & how-tos

How to adjust Google Analytics 4 settings to reduce unassigned traffic
Step 1: Extend the Adjust Session Timeout Setting

By default, GA4 ends a session after 30 minutes of inactivity. If a customer starts a checkout, leaves their browser tab open for over 30 minutes, and then returns to complete the purchase, GA4 creates a brand-new session. If the original campaign parameters or referring headers are no longer present on that late interaction, the second session loses context and falls into Unassigned or (direct).

FIX:

  • Go to Admin > Data Streams > [Your Web Stream] > Configure Tag Settings.
  • Click Show All and select Adjust Session Timeout.
  • Increase the Adjust session timeout slider from 30 minutes up to 7 hours and 55 minutes.
Step 2: Set Up Custom Channel Groups

GA4’s Default Channel Group uses strict rules. If your clients use custom UTM mediums (e.g., utm_medium=paid-social vs GA4's expectation of paidsocial, or utm_medium=pdf, utm_medium=newsletter_app), GA4 marks them as Unassigned.

FIX:

  • Go to Admin > Data Display > Channel Groups.  Click Copy to Create New (based on the Default Channel Group).  Create explicit channel rules matching your client's custom UTM patterns (e.g., map utm_medium = paid_ad to Paid Shopping or a custom channel).
Step 3: Configure List Unwanted Referrals

Payment gateways (PayPal, Klarna, Stripe) or external OAuth providers create self-referral loops. When a user returns from payment, GA4 starts a new session driven by paypal.com. If GA4 can't reconcile the session, it gets dumped into Unassigned or overwrites the original marketing source.

FIX:

  • Go to Admin > Data Streams > [Your Web Stream] > Configure Tag Settings.
  • Click List Unwanted Referrals.
  • Add domain patterns for all payment processors (e.g., paypal.com, checkout.stripe.com, klarna.com).
Step 4: Configure Cross-Domain Auto-Linking

If a client operates across subdomains or separate checkout domains, moving across them without the _gl URL parameter strips session cookies, causing destination events to fire as Unassigned.

FIX: 

  • Go to Admin > Data Streams > [Your Web Stream] > Configure Tag Settings.
  • Click Configure Your Domains.
  • Enter all top-level domains involved in the journey.
Step 5: Adjust the Reporting Date Range (The 48-Hour Processing Window)

GA4 processes campaign attribution asynchronously. Freshly arriving data within the last 24 to 48 hours often temporarily appears as Unassigned while Google’s backend correlates user IDs, session parameters, and ad-platform conversions. Always exclude today and yesterday when evaluating Unassigned metrics in reports to avoid diagnosing temporary data processing lags as actual tracking failures.

Extensions for Magento

Anowave is an extension developer for Magento 1.x and Magento 2.x platforms. We provide a wide range of premium extensions for our in-house and public clients. The extensions we offer extend the capabilities of Magento and provide bespoke functionality. They also fill some gaps in the functionality provided by the base platform and help customers choose Magento as their preferred eCommerce platform.

The extensions we offer are part of our full-range Magento service, which also includes a Premium Helpdesk where customers can speak with actual software engineers and have their issues resolved without hassle. Premium-labeled modules also include free installation, configuration, testing, etc.