Tracking accuracy

GA4 "(not set)": every cause and how to fix it

Why GA4 shows (not set) for landing page, source, medium and campaign, how to tell which cause you have, and the fix for each one.

On this page

"(not set)" is not a source, a page or a campaign. It is the placeholder GA4 writes when it received no value for a dimension (Google). So the question is never "what is (not set)?" but "why did this value never arrive?" The answer depends on which dimension you are looking at.

This guide goes dimension by dimension, with a test for each cause. It sits next to why analytics numbers never match: (not set) is one of the ways GA4 parts ways with your other tools.

First, find out which (not set) you have

Open the report where you saw it and note the dimension. The causes barely overlap:

Where you see (not set)What is missingMost common cause
Landing pageA page_view in the sessionThe session started on an event, not a pageview
Session source / mediumThe session_start eventTag order, or consent mode set up wrong
Session campaignCampaign informationA tag missing utm_campaign, or untagged traffic
Google Ads reports (campaign, keyword)A link from the click to the accountAds not linked, or auto-tagging off
A custom dimensionThe parameter on that eventRegistered less than 24 hours ago, or never sent

Two lookalikes are different problems. (other) is GA4 folding rare values into one row when a table passes its row limit (Google). (data not available) is a related placeholder that you usually cannot reduce (Google).

Landing page: (not set)

GA4 shows (not set) as the landing page when a session has no page_view event (Google). The landing page is read from the first pageview, so a session without one has nothing to show.

How a session ends up with no pageview:

  • A tab left open past the timeout. A GA4 session ends after 30 minutes without activity by default (Google). When the visitor comes back to the open tab and scrolls or clicks, that event starts a new session. No page loaded, so no page_view.
  • Events fired before the pageview. A Tag Manager event tag that fires before the Google tag sends its config sends an event with no session context. Google's advice is to initialize the Google tag before any event (Google).
  • Pageviews turned off. Some single-page app setups disable the automatic page_view and send their own, and one route never sends it.
  • Server events. Events sent with the Measurement Protocol create activity on the server, where no page was viewed.

Fix: in Tag Manager, fire the Google tag on Initialization - All Pages and every event tag after it (Google). Then check single-page app routes in DebugView: each route change should send one page_view. A small share of (not set) from returning tabs is normal and cannot be removed.

Session source / medium: (not set)

Session source and medium read (not set) when the session has no session_start event (Google). Those sessions also fall into Unassigned in the default channel group, because no channel rule matches them. The causes Google names:

  1. The Google tag fires too late. In Tag Manager, the Google tag should use the Initialization - All Pages trigger, not a later one.
  2. Consent mode set up with the wrong command. Using default to record the visitor's answer, instead of update, means the event that carries session_start is lost.
  3. Denied events after a yes. Sending more events with denied consent after the visitor agreed makes GA4 treat them as a separate session with no session_start.

Google also notes a quirk of Google Search: sessions that carry the srsltid parameter but no google.com referrer can show (not set). That happens when people share a modified link, and those sessions are not counted as organic (Google).

Fix: move the Google tag to the Initialization trigger, then review your consent banner's integration with consent mode. The banner should call gtag('consent', 'default', ...) once, before the Google tag loads, and gtag('consent', 'update', ...) when the visitor answers.

Session campaign: (not set)

Campaign is (not set) for every visit that carried no campaign. Organic, referral and direct visits have no campaign by nature, so a large (not set) row here is expected.

It becomes a problem when paid traffic lands in it:

  • Tags missing a value. A link with utm_source and utm_medium but no utm_campaign arrives with a source and no campaign. Google lists incomplete or incorrect UTM tags as a cause (Google).
  • Tags stripped by a redirect. A redirect that drops the query string removes the UTM parameters and the click id, and the visit loses its campaign and often its source too.

Fix: use all three required tags on every link you control, written the same way every time. Test landing pages with ?utm_source=test&utm_medium=test&utm_campaign=test and confirm all three survive every redirect.

In GA4's Google Ads reports, (not set) means GA4 could not tie the session to a click in a linked account. Google lists the causes (Google):

  • Google Ads and GA4 are not linked.
  • Auto-tagging is off, so clicks arrive without a gclid.
  • Another Google Ads account advertises your site and is not linked to this property. Its clicks carry a gclid that GA4 cannot map.
  • Manual UTM tags that are incomplete or wrong.

Fix: link every Google Ads account that sends traffic, turn on auto-tagging in each, and check that the gclid reaches your landing page. If a site or plugin strips unknown query parameters, the gclid goes with them.

Custom dimensions: (not set)

Two causes cover nearly every case (Google):

  • It is new. For the first 24 hours after you register a custom parameter, its value can show as (not set).
  • The event does not carry it. A custom dimension is per event. A report that mixes events, such as page_view with session_start, shows (not set) for the events that never had the parameter. Content groups do the same with automatically collected events, which do not accept content_group.

Fix: wait a day after registering. Then filter the report to the event that sends the parameter, and confirm the parameter in DebugView.

A worked example

Example numbers, made up for illustration. A store sees 1,240 sessions in a week with landing page (not set), out of 18,600. Its steps:

  1. Break down by event name. Most (not set) sessions start with user_engagement or scroll, not page_view. That points to sessions restarted in an open tab.
  2. Break down by device. The share is far higher on desktop, where tabs stay open all day. That fits.
  3. Check Tag Manager. The Google tag fires on All Pages, after two event tags on Initialization. Those event tags fire before the config.
  4. Fix and compare. After moving the Google tag to Initialization - All Pages, the share falls the next week. The rest is returning tabs, which is expected.

How to keep (not set) small

  • Fire the Google tag first, on the Initialization trigger.
  • Send consent defaults before the tag, and updates with update.
  • Tag every link you control with utm_source, utm_medium and utm_campaign.
  • Link every Google Ads account and keep auto-tagging on.
  • After any site change, open a landing page with test tags and read DebugView.

Most of the same habits also shrink direct traffic, since a lost tag shows up in one or the other.

Common questions

What does (not set) mean in GA4?

It is a placeholder for "no value received". GA4 shows it when a dimension had no data for that row: no pageview for the landing page, no session_start for the source, no campaign tag for the campaign.

Is (not set) the same as direct traffic?

No. Direct is a source: GA4 received the session and found no referrer, tag or click id. (not set) means a value never arrived at all, often because of how the tag was set up.

Why is my landing page (not set) in GA4?

The session had no page_view event. The usual cause is a visitor returning to an open tab after the 30-minute timeout, so a scroll or a click started the new session. Event tags firing before the Google tag cause it too.

Why does Unassigned go up with (not set)?

A session with source and medium (not set) matches no channel rule, so it lands in Unassigned. Fix the source and Unassigned shrinks with it.

Can I remove (not set) from old reports?

No. GA4 processes data as it arrives. Fixes apply from the day you make them.

Sources

Spotted something wrong or out of date? Email hello@sporetag.com and we will fix it.