(Not Set) in GA4: What It Means and How to Fix It

Show article contentsHide article contents
Open any GA4 property and you will find (not set) sitting in your reports. Every property has it. The question that matters is not how to make it disappear. It is which half of it you can fix.
Some (not set) is a configuration issue. You move a tag, you fix it, it takes 10 minutes. The rest is architectural. It is data that was never collected, and no setting in the world brings back data GA4 never received. So the trap is treating all of it the same. You spend a week chasing tags that were never the problem. Here is how to tell the two apart.
- (not set) means GA4 received an event but has no value for that dimension. It is missing data, not an error message.
- Landing page shows (not set) when sessions start without a page_view event. Session timeouts, consent delays, and GTM misconfiguration are the top causes. A well-configured property stays under 5%.
- Source/medium shows (not set) when GA4 cannot determine where the visitor came from. Consent denial, dark social apps, and in-app browsers are the primary drivers.
- Most fixes are not retroactive. Once GA4 collects data incorrectly, the gap is permanent. Only reporting-layer changes (like the February 2024 Google Signals removal) affect historical data.
- Cookieless analytics tools avoid the consent and attribution gaps entirely because they read referrers directly and do not depend on cookies for session attribution.
What (not set) actually means
(not set) is the label GA4 puts in a cell when it got no value for that dimension. It is not an error. Nothing broke while GA4 crunched the numbers. The value was just never sent in the first place.
That is the whole story. And almost everyone misses it. GA4 has five different labels for data it can't show you, and people treat all five as one thing. They are not the same thing.
One distinction decides what you do next. (not set) means the data is genuinely gone. (other) means GA4 collected the data fine but is hiding it because the table ran out of room. Unassigned means the data is there and GA4 just can't sort it into a channel. Three different problems. Three different responses. Filtering the (not set) rows out of your report fixes none of them. It only hides the symptom.
Why landing page shows (not set)
GA4 fills the landing page dimension from the page_location parameter on the first page_view event of a session. So if a session has zero page_view events, there is nothing to fill it with. Landing page becomes (not set). Not "unknown." Not "the page they were on." Missing.
Session timeout re-engagement. A visitor opens your pricing page at 2:00 PM. They leave the tab open and go to lunch. At 2:31 PM they come back and scroll. GA4's default 30-minute timeout has run out, so it starts a fresh session. The scroll fires a user_engagement event. No page_view fires, because the visitor never went to a new page. The new session has engagement data and no landing page. This hits media sites, SaaS dashboards, and ecommerce product pages hardest. Anywhere people leave tabs open.
GTM tag firing order. Tags fire in an order. If your Google Tag fires on "All Pages" instead of the "Initialization" trigger, a custom event tag can sneak in first. The session starts before page_view is sent. The fix is one click: move the Google Tag to the Initialization trigger in GTM.
Consent timing. A visitor scrolls or clicks before they accept the cookie banner. If GA4 runs in Advanced Consent Mode, that scroll triggers a user_engagement event and a session starts. The page_view waits. It may not fire until the visitor grants consent on a later page. Landing page: (not set).
What good looks like. On a well-configured property, (not set) landing pages stay under 5% of sessions. Above 20% and something is broken. Go check your GTM tag firing order and your consent setup. Data Bloo's GA4 audit tool flags anything over 2% of page views.
Why source/medium shows (not set)
To figure out source/medium, GA4 has to read either the document.referrer or the UTM parameters at the start of a session, then tie that to the session with cookies. It is a chain. Break any link in it and source/medium goes to (not set).
Consent mode strips session identifiers. In Advanced Consent Mode, when a visitor denies cookies, GA4 sends "cookieless pings" that drop the user_pseudo_id and the session_id. Each page load is now an orphan event with no session around it. GA4 has nothing to tie it to a source. Google can model some of this data back, but the bar is high: at least 1,000 daily consenting users for 7 of the past 28 days and 1,000 daily denied events for at least 7 days. A site under 2,000 daily visitors almost never clears it.
Dark social strips referrer headers. 69% of all sharing, nearly seven links in ten, happens in channels that pass no referrer data at all: WhatsApp, Slack, email clients, Facebook Messenger, SMS. A link someone sends you on WhatsApp opens in your browser with no referrer attached. GA4 logs it as direct, or as (not set). The Groupon experiment showed how big this gets. Groupon de-indexed from Google for 6 hours, and 60% of their "direct" traffic vanished. It had been organic search the whole time.
In-app browsers corrupt attribution. Tap a link inside the Facebook, Instagram, or TikTok app and it opens in an embedded WebView. That WebView often strips the referrer header on the way through. One fashion brand could see only 10% of its mobile ad traffic in Google Analytics. The in-app browser hid the other 90%.
The benchmarks. On a properly tagged site with mostly non-EU traffic, source/medium (not set) stays under 5%. Move to EU markets with compliant consent banners and consent mode alone can push it above 30%. Almost a third of your sources, gone. You can't fix that with a setting. It is baked into how the tracking works.
The fixes (and what they cannot fix)
Every fix below shares one trait. It only touches future data. This is the part you need to hold onto. Once GA4 has logged a session with no attribution data, that gap is there for good. You can't go back.
The configuration fixes are real, and they are worth doing. Move the Google Tag to the Initialization trigger. Register your custom dimensions today. Link all your Google Ads accounts. And if your users leave tabs open, push your session timeout up from the default 30 minutes toward the 7 hours 55 minutes maximum.
None of them touch the deeper causes, though. Consent-denied visitors. Dark social. In-app browsers. Ad blockers. These are not settings you forgot to flip. They are what you get when your analytics runs on cookies and client-side JavaScript. The gaps come with the design.
What (not set) costs you
(not set) is not a cosmetic annoyance. It quietly bends every decision you make off your analytics.
On a typical ecommerce site, 30-40% of conversion data lands in catch-all buckets like Direct and Unassigned. That is up to four sales in ten with no traceable source. The purchases happened. The revenue is real. GA4 just can't tell you which campaign, ad, or referrer brought the buyer in.
That feeds straight into automated bidding. Google Ads Smart Bidding optimizes against the conversions GA4 reports. So when 30% of conversions are invisible, Smart Bidding reads your campaigns as worse than they are and pulls money out of campaigns that were making you money. It chases channels that are easy to track, not the ones that earn the most.
In the EU it gets worse. With up to 60% data loss on legally compliant consent banners, GA4 is blind to the source of most of your European visitors. Google's behavioral modeling is meant to patch the hole, but it needs volume thresholds that most small and medium sites never hit. So here is what you see: your EU traffic appears to convert at half the rate of your US traffic. It doesn't. You just can't see the conversions it makes.
Want the number for your own site? Drop your region and industry into the GA4 Data Loss Estimator. It folds (not set) into the "internal limits" and "consent rejection" drivers and shows you how much of your traffic is unmeasured versus how much is merely unattributed.
Analytics without (not set)
Clickport reads the referrer straight from the browser when the page loads. No cookies. No session rebuilt after the fact. Nothing waiting on consent. A visitor arrives from Google and document.referrer says google.com. A visitor arrives from an email link and the referrer is the email client's domain, or empty. Either way there is nothing to reconstruct, nothing to model, and nothing for a consent rejection to take away.
Unknown source → (not set)
No page_view → (not set) landing page
Unknown country → (not set)
Consent denied → Invisible or modeled
500+ unique values → (other)
Unknown source → Raw hostname shown
Every request → Landing page always captured
Unknown country → Excluded (no false labels)
No consent needed → Every visitor counted
No cardinality bucketing → No (other) row
Every dimension carries a real value you can read. Placeholder labels are gone. So is the data that GA4 tucks behind its processing thresholds. And so is the 24 to 48 hour wait for reports to fill in.
I won't oversell it. The referrer is not always there to read. Dark social strips referrer headers no matter which analytics tool you run, and Clickport is no exception. But the consent gap, which is the single biggest driver of (not set) in EU markets, is simply gone. No cookies means no consent banner. No consent banner means no 40-60% data loss. Every visitor gets counted, attributed to whatever referrer the browser hands over, and shows up in your dashboard within 30 seconds.
Start your free 30-day trial. No credit card. One script tag. No (not set).
Frequently asked questions
What does (not set) mean in GA4?
(not set) means GA4 got an event or a session but has no value for one of its dimensions. It is not an error message. It means the information never arrived: no landing page URL, no referrer, no campaign parameter. Each dimension goes (not set) for its own reasons, and each one needs its own fix.
Can (not set) be completely eliminated from GA4?
No. Analytics Mania says it plainly: "In some situations, it is possible to fix and remove not set. In other situations, it is possible to reduce how often it appears. And in the rest, it is just something we will need to accept." Session timeouts, consent denial, dark social, ad blockers. They all create (not set) that no setting can undo.
Is (not set) the same as direct traffic?
No. Direct traffic shows up as (direct) / (none) in source/medium. GA4 means that on purpose: someone typed your URL, used a bookmark, or came from a source GA4 couldn't name. (not set) is different. GA4 never got to try, because the attribution data wasn't there at all. Direct is a fallback answer. (not set) is no answer at all.
What is the difference between (not set) and Unassigned?
(not set) means the data is missing. Unassigned means the data is right there, source and medium can both be filled in, but it doesn't match any of GA4's 18 default channel rules. The usual culprit is an off-script utm_medium value: "newsletter" instead of "email," "partner" instead of "referral." Fix it by using medium values that GA4's channel rules already know.
Does BigQuery fix the (not set) problem?
Partly. BigQuery gets the same raw event stream as GA4, only without the thresholding, the sampling, or the row limits. So it can pull back gclid-based paid search attribution that GA4 mislabels, and it can surface custom dimension values you never registered. What it can't do is recover data nobody collected. If consent blocked the event, the tracker never fired, or the page had no title tag, BigQuery is just as blind as GA4.

Comments
Loading comments...
Leave a comment