← All resources Guide

GA4 "Unassigned" and "(not set)" traffic after moving server-side

A week after switching to server-side tagging, someone opens the Traffic acquisition report and finds a new channel at the top: Unassigned. Next to it, sessions whose source reads (not set). The move gets the blame, and sometimes it deserves it. More often the cause is one of five things, and four of them have nothing to do with where your container runs. Here is how to tell them apart.

What the two labels mean

Unassigned is a channel group. GA4 knows the session's source and medium, but neither matches the rules of any default channel: utm_medium=newsletter, utm_medium=banner or utm_source=chatgpt.com without a medium all end up here. (not set) is different: GA4 does not know the value at all. For session source it means GA4 never saw the event that opens the session, so it has nothing to attribute the rest to.

First, wait four days

GA4 attributes sessions in stages and reprocesses the most recent days. On a report that ends yesterday, part of the last few days is still Unassigned and will move to the right channel later. On the properties we check, nearly every Unassigned session sits in the last four days. The Measurebase audit reads channel reports with a window that ends four days ago for exactly this reason. Before you debug anything, set the date range to end four days ago and look again. If Unassigned shrinks to a few percent, you have no problem.

Cause 1 · Your own UTM values

The default channel rules only recognise a fixed list of mediums: cpc, ppc, paid, email, social, referral, affiliate, display, video and a few more. Anything else is Unassigned, however sensible it looked in the campaign builder. Check the Session source / medium dimension under the Unassigned row: if you see your own mediums, rename them in future links or add a custom channel group that maps them. Server-side tagging does not touch UTM values, so this cause predates the switch.

Cause 2 · Two tracking paths for one visitor

This one is the move's fault. If some GA4 tags send to your server container and others still send to Google directly, or if the old Tag Manager snippet is still on the page next to the new one, a visitor's session is split over two paths. GA4 can receive a purchase through one path for a session whose first page view arrived through the other, with different cookies or client IDs, and the purchase lands in a session it never saw begin: source (not set), channel Unassigned. The same happens when an ad blocker stops the browser hit while a server-side copy of the event still arrives.

Fix: every Google tag in the web container gets the same server_container_url, the old snippet goes, and the Enhanced script carries the page views past blockers so the first event of a session arrives on the same path as the rest. The audit reports the share of Google hits that bypass your server container and which tag sends them; the guide on hits that bypass your server container walks through the fix.

Cause 3 · Server-to-server events without a session

A purchase sent from your shop's backend, a webhook or the Measurement Protocol arrives without the browser's context. If it does not carry the visitor's client_id, the current session_id and an engagement flag, GA4 cannot place it in the session where the visitor actually was, and it shows up with source (not set). Purchases are the events people look at most, so a handful of these stand out.

Fix: server-sent events must reuse the identifiers from the browser session. Our Shopify app does this for the order relay: it merges the browser's identity into the server-side purchase before it goes out, so the purchase joins the session that produced it. For your own server-to-server events, store client_id and session_id with the order and send them along.

Cause 4 · The referrer never arrived

Session source for an unlabelled visit comes from the referrer. Three things make it disappear: a Referrer-Policy of no-referrer on the linking site or your own, in-app browsers that strip it, and single-page apps that fire their page views after the router has already changed the URL, so page_referrer is your own site. A transformation in the server container that removes page_referrer or page_location does the same. A missing referrer usually becomes Direct, but a referrer that points at your own domain becomes a self-referral or, combined with a lost session start, (not set).

Fix: keep page_location and page_referrer on every event (the Measurebase import never strips them), add your own domains to the unwanted referrals list in the GA4 data stream, and in a single-page app send the page view before the route changes or pass the previous URL as page_referrer yourself.

With Consent Mode, visitors who refuse send cookieless pings. GA4 only fills the gaps with behavioural modelling when the property meets the thresholds; until then, those sessions are missing rather than Unassigned, but the ones that straddle a consent choice can lose their start. A visitor who lands, refuses, browses, then accepts on the checkout page starts a new identity halfway through: the purchase has a session, the session has no source. The consent trend in your Measurebase domain statistics shows how many hits arrive granted, denied or without any consent state, which tells you how much of your traffic lives in this grey zone. The guide on Consent Mode v2 server-side covers the setup.

How to find out which one you have

  1. Traffic acquisition, date range ending four days ago, primary dimension Session default channel group. Note the Unassigned share.
  2. Add Session source / medium as a secondary dimension. Your own medium names mean cause 1.
  3. Switch to Session source and look for (not set). Then open an exploration with event name against session source: if (not set) is mostly purchases or lead events, suspect causes 2 and 3; if it is spread over all events, suspect 2 or 5.
  4. In Measurebase, open the domain's request logs during a test visit: the page view and the purchase should both arrive at your server container, with the same client ID, on one path. The audit's bypass and duplicate findings tell you if they do not.
  5. Compare the Unassigned share for the weeks before and after your switch date. A step change on that date points at cause 2; a flat line says the move is innocent.

What Measurebase checks for you

The nightly tracking audit reports Google hits that bypass your server container, a second container or old snippet on the page, tags that send without the shared server URL and events that fire before consent. With the GA4 property connected, it reads the property's channel reports with the four-day settling window and compares the hits it saw with what GA4 recorded, counting only consented, human, successful hits, because GA4 shows nothing for denied pings. The request logs show every event with its consent state, so a split path or a missing session start is visible per visit.

Frequently asked questions

Will the historical Unassigned traffic repair itself?

Only the most recent days are reprocessed. Older sessions keep the attribution they got; fixing the cause changes what you see from now on.

Is Unassigned the same as Direct?

No. Direct means GA4 saw no source at all and assumed the visitor typed the address. Unassigned means it saw a source and medium that no channel rule accepts.

Does server-side tagging cause Unassigned traffic by itself?

No. When every Google hit goes through one path and server-sent events carry the browser's identifiers, GA4 sees exactly what it saw before, from a different address. The problems come from running two paths at once, or from sending events the browser never knew about.

Continue reading

Ready to move your tagging to Europe?

Start free, no credit card required. Live in about 15 minutes.

Start free