Open the Traffic acquisition report in Google Analytics 4 and one row stands out. It either says Unassigned, in the channel group column where you expected Paid Search or Email. Or you see (not set) in the session source / medium column for conversions you know came from somewhere. Seeing excessive amount of traffic attributed to either indicates the same problem: GA4 received the event but couldn’t connect it to a session that had traffic source information. This guide explains what the (not set) / Unassigned labels mean, how to track down the sessions behind them, and what to change so your conversions land in the right channel.
Two labels, one missing session
GA4 records session source and medium once, when a session starts. Every event in that session then inherits them, and the default channel group is derived from the pair: google / cpc becomes Paid Search, klaviyo / email becomes Email, and so on.
When an event arrives without a session start, or after the session has ended, there’s nothing to inherit. The session source / medium shows as (not set), and because (not set) doesn’t match any channel rule, the session default channel group shows as Unassigned. If you filter your conversions down to the ones marked Unassigned and switch the dimension to session source / medium, you’ll typically find they’re all (not set). That’s the signature of the problem: it isn’t that GA4 misidentified the channel, it’s that the traffic source never gets associated with the event.
Occasionally Unassigned appears on its own, with a real source and medium next to it. That happens when a UTM medium doesn’t match GA4’s channel definitions, such as utm_medium=newsletter rather than email, and it’s fixed by aligning the UTMs with Google’s default channel rules or by defining a custom channel group. It’s worth ruling out, but if your Unassigned rows are mostly or entirely (not set), the sections below are where the answer is.
Why session source shows as (not set)
A (not set) session source almost always comes back to one of three things.
The session had already timed out. GA4 closes a session after 30 minutes of inactivity by default, and some properties have this reduced further. A visitor who lands from a Google ad, opens a checkout or booking page, gets distracted and comes back forty minutes later to complete the purchase fires a conversion event with no new page view before it. The event lands outside any active session, so it has no session source.
The event was sent server-side without a session. In third-party integrations, Purchases confirmed by a payment webhook, leads created in a CRM and conversions imported offline are often sent to GA4 through the Measurement Protocol. If the request doesn’t include a valid session_id from the visitor’s active session, or if it arrives long after that session ended, GA4 reports the session source as (not set). This is the usual culprit when page views attribute correctly but purchases don’t, and it’s why a property can show close to 100% Unassigned on its conversion events while its sessions look healthy. Able’s Google Analytics 4 Measurement Protocol integration solves this by always sending the last known session_id with any event, even tracked offline or server-side.
The data hasn’t finished processing. Session source is populated during GA4’s data processing, which can lag by 24 to 48 hours. Conversions from the last day or two in standard reports, and everything in the Realtime report, can show (not set) temporarily and then resolve. If the problem only affects very recent data, wait before changing anything.
How to investigate a missing session source
Before changing settings, it’s worth confirming what GA4 actually received for a specific conversion. It’s possible the data is fine and the report is the problem, or that there’s something unusual about the session history rather than about the conversion event itself. Working through one real example will tell you which.
-
Pick a recent conversion and find its Client ID. In the Able Dashboard, open a customer with a recent purchase or lead event and locate their Google Analytics Client ID, stored as
ga_cookie. It looks like two numbers separated by a dot, for example1496406184.1790779193. If you’re not using Able, you can read the same value from the_gacookie in the browser of a test conversion. -
Check the timing against your session timeout. Look at the customer’s event history and note how long passed between their last page view and the conversion. Compare this with the session timeout configured in your GA4 property under Admin → Data Streams → Configure tag settings → Adjust session timeout. The default is 30 minutes, but it’s worth checking rather than assuming, since it may have been lowered. If the gap is longer than the timeout, you’ve found your cause.
-
Look the user up in GA4’s User Explorer. Open an Exploration, choose the User explorer technique and search for the Client ID. Google’s User Explorer guide walks through the interface. Open the conversion event and check what arrived with it: was there an active session at the time, what session source does GA4 show for the event, and was the preceding landing page view tracked at all?
What you see in User Explorer tells you where to look next. If the landing page view is missing, the tracking tag isn’t firing on that page or consent is blocking it. If the page view is there but the conversion fired after a long gap, it’s a session timeout issue. If the conversion arrived with no session ID at all, the server-side integration isn’t passing one. And if User Explorer shows the correct source on the event but the aggregate report still says (not set), the problem is in how the report is built, not in the data, and a different report or an Exploration may already give you the answer.
Fixing (not set) session sources
Once you know the cause, the fix is usually one of the following.
Extend the session timeout. If conversions typically happen after a pause, raising the timeout towards its maximum of 7 hours 55 minutes keeps more of them inside their original session. This is the lowest-effort change and often the most effective one for longer checkout and booking flows.
Send the session with server-side events. Measurement Protocol events need the visitor’s client_id and the session_id of their active session to inherit a session source. Able CDP’s server-side Google Analytics integration records both identifiers when the visitor first arrives and sends them with every purchase, lead or subscription event, including ones confirmed by webhooks hours later. The conversion then appears in GA4 as part of the session that produced it, and moves from Unassigned to its real channel.
Make sure the first page view is tracked. Session source comes from the landing page. If consent banners, ad blockers or a slow-loading tag prevent that first hit from firing, GA4 has no source to record even if everything after it works. Testing a conversion with consent declined is a quick way to see how much of your (not set) traffic this explains.
Keep cross-domain tracking intact. When the conversion happens on a different domain, such as a hosted checkout or booking page, the Client ID needs to carry across. A broken cross-domain setup produces a new session on the second domain with a referral source from your own site, or none at all.
When GA4 sessions aren’t the right tool
Even with every fix in place, GA4 session attribution has limits. Sessions expire, cookies get cleared, and a visitor who first found you three months ago and converted today is attributed to whatever brought them back, not to what brought them in. For revenue reporting, that’s often the wrong question.
Able CDP records first-touch and last-touch attribution for every lead and purchase at the visitor level, independently of GA4 sessions, so a conversion never loses its source to a timeout. Basic first-touch attribution reporting is available from the Explore button next to any chart in the Able Dashboard.
To investigate a specific batch of Unassigned or (not set) conversions, connect Able’s marketing attribution MCP server to Claude, ChatGPT or another AI assistant. You can ask which campaigns the affected purchases came from, break them down by UTM source or referrer, or compare them with the conversions GA4 did attribute, all in plain language and without exporting anything. The analytics MCP server queries Able’s visitor-level data directly, which makes it the quickest way to close an attribution gap. For teams that want the raw events in their own warehouse, the BigQuery connector syncs every conversion with its UTM parameters and referrer URLs.