You open Traffic acquisition and see a growing slice of GA4 unassigned traffic, sitting next to a Direct line that keeps climbing. Neither tells you where those visitors came from, so you can’t tell which campaigns worked.
Unassigned and Direct are two different tracking problems, and each one has its own cause and its own fix.
This audit guide shows you how to find out what GA4 actually received for those sessions. It then covers how the default channel rules sort them and which UTM, tag or referrer issues to fix first.
It also explains the mid-October 2026 Direct spike caused by the ChatGPT UTM bug. You’ll learn how to confirm it in your own property and why past data won’t be corrected.
The guide is written for small business owners, WooCommerce store owners, marketers and in-house SEOs who use GA4 every week. You don’t need to be an analytics specialist.
Work through it in order. Run the 15-minute audit first, then fix the causes it shows you.
Key Takeaways
- Unassigned means GA4 got source or medium values matching no channel rule.
- Direct means GA4 received no referrer and no UTM parameters at all.
- Custom utm_medium values like newsletter, qr and influencer usually cause Unassigned.
- Use plain lowercase platform names for utm_source, like facebook or instagram.
- The ChatGPT UTM bug pushed AI visits into Direct between 8 and 15 October.
- Google's default channel group can't be edited; use custom channel groups instead.
- Always audit in the session scope before comparing user or event scopes.
What GA4 Unassigned and Direct traffic actually mean
Unassigned and Direct often get grouped together as “traffic we can’t explain”. They are different problems, and each needs a different fix.
Before you change anything, you need to know what GA4 actually received for each session. That tells you whether to fix your links, your tags or your referrer handling.
Unassigned: GA4 got a source or medium it can’t match to a rule
Google defines it plainly: “Unassigned is the value Analytics uses when there are no other channel rules that match the event data” (Google Analytics Help).
In most cases, GA4 did receive source and medium values, but they matched none of the default channel rules. The usual cause is a home-made utm_medium value.
Likely Unassigned (source and medium both unrecognised):
?utm_source=april_promo&utm_medium=newsletter
?utm_source=flyer&utm_medium=qr
?utm_source=summer_launch&utm_medium=influencer
Matches a rule:
?utm_source=april_promo&utm_medium=email → Email
?utm_source=unknown_network&utm_medium=cpc → Paid Other (medium contains "cp")
Two edge cases matter here:
- A recognised source can rescue a bad medium. Some rules check the source against Google’s lists of social, search and video sites.
utm_source=facebook&utm_medium=fbcan still land in a social channel. - Sessions can also lose their source entirely. This happens with Measurement Protocol or server-side events sent without a valid
client_idorsession_id, and with events that fire before the Google tag config. Several audit guides report these ending up in Unassigned (Scandiweb).
Google maintains a single default channel group, and nobody can edit it. Check the current list of channels and rules on the official page, because third-party guides give different channel counts.
Direct: GA4 got no source information
Google’s Direct rule is strict: source is exactly (direct) and medium is (not set) or (none) (Google Analytics Help).
In other words, the visit arrived with no referrer and no UTM parameters. GA4 isn’t misreading anything here, because it never received anything to read.
“Direct traffic means people typed my URL into the browser.”
Some of it does. A large share, though, is referral or campaign traffic that lost its source on the way:
- Links from HTTP pages to an HTTPS site.
- Links with
rel="noreferrer". - Email apps and messengers that send no referrer.
- AI assistants that strip the referrer.
Ad blockers cause a separate problem. They stop the tag from loading at all, so those visits are not recorded anywhere (Nativeore Analytics).
| Bucket | What GA4 received | Typical causes | First thing to check |
|---|---|---|---|
| Unassigned | A source or medium that matches no rule, or a session whose source was lost | Custom utm_medium values (newsletter, qr, influencer); server-side hits without session IDs; events fired before config |
Session source / medium for Unassigned sessions |
| Direct | (direct) / (none) or (not set) |
Missing referrer, untagged email or app links, noreferrer, HTTP-to-HTTPS links, AI platforms with no referrer |
Landing page + query string for Direct sessions |
Why both are data-quality signals, not channels
Neither bucket describes how people found you. Each one describes what your tracking failed to capture. Treat a rising share as a bug report.
Also check which scope you are looking at, because the numbers won’t match across reports:
- Session default channel group (Reports > Acquisition > Traffic acquisition) classifies each session.
- First user default channel group (User acquisition) classifies how the user first arrived.
- Event-scoped default channel group is used for key event attribution. It shows
(not set)for events that aren’t key events, and that is expected.
The same person can show as Direct in one scope and Unassigned in another. Always audit in the session scope first.
Why Direct and Unassigned spiked in October 2026
If your Direct line jumped in mid-October, a tracking change at one AI platform is the likely cause. Your site probably did nothing wrong.
The ChatGPT UTM bug (8–15 October)
Around 8 October 2026, close to the GPT-6 rollout, ChatGPT links stopped adding utm_source=chatgpt.com. They also still sent no referrer, so those visits landed in Direct (Search Engine Land).
Adobe’s Cedric Huesler analysed about 500 pages. On those pages, ChatGPT lost roughly 31k visits a day while Direct gained roughly 26k (Search Engine Journal). Other sources showed the same pattern:
- LLM Pulse reported a drop of about 46%.
- Graphite’s GA4 data showed drops of 22% to 57%.
OpenAI confirmed it was a bug. Tags started returning from about 15 October (Search Engine Journal).
Gemini adding, then removing, UTMs
Gemini began adding UTMs to cited links in early September 2026. It stopped around 28 September (Search Engine Roundtable).
If Gemini visits showed up briefly in September and then fell away, check whether they moved into Direct.
What changed and what stayed broken
- Past data is not corrected. Sessions from 8–15 October stay in Direct.
- Most ChatGPT clicks still send no referrer, so the UTM remains the main signal.
- GA4’s AI Assistant channel (added 13 May 2026) depends on Google’s referrer list. Google does not publish the full list, and the channel doesn’t apply to data from before the change. Copy the exact channel label from Google’s help page if you filter on it.
The general lesson applies to every AI platform. When a platform blocks the referrer, the UTM is the only signal left, and the platform controls it, not you. It can disappear overnight without notice.
Here is how to check your own property:
- Add a GA4 annotation covering 8–15 Oct 2026 that reads “ChatGPT UTM bug, AI visits in Direct”. If you can’t create annotations, log the date range in your reporting notes.
- Go to Explore > Free form. Add the dimensions Landing page + query string and Session source / medium, and the metric Sessions.
- Compare 1–7 Oct with 8–15 Oct.
- List the pages that normally get
chatgpt.comsessions, then check whether Direct sessions rose on those same pages.
Filter A: Session source contains "chatgpt" (1–7 Oct) → note top landing pages
Filter B: Session source exactly "(direct)" (8–15 Oct) → same pages rising? = bug, not lost demand
For a full AI setup, see how to track ChatGPT search traffic in GA4 and the complete AI referral tracking guide.
The October spike is only one example. The same checks apply to email, social, QR codes and payment gateways, and the rest of this audit covers every channel.
How GA4’s default channel group rules decide where a session goes
Every session gets a channel from one default channel group that Google maintains for all properties. You can’t edit it, rename a rule or add a medium to it. This is why custom channel groups exist (covered in section 9).
To fix Unassigned, you need to know how those rules read your source, medium and campaign values.
Rules run in order and the first match wins
GA4 checks the session’s source, medium and campaign against each channel definition in order. The first channel whose conditions match gets the session. If none match, the session becomes Unassigned.
- Direct is checked first. It needs source exactly
(direct)and medium(not set)or(none). - Paid channels (Paid Search, Paid Social, Paid Shopping, Paid Video) need a recognised source and a paid-looking medium.
- Paid Other catches paid-looking mediums from sources GA4 doesn’t recognise. It does this because the medium contains
cp, equalsppcorretargeting, or starts withpaid. - Organic channels match on a recognised source or a specific medium, such as
organicorsocial. - Unassigned is the fallback when nothing else fits.
This order explains why google / cpc lands in Paid Search but mybrandpartner / cpc lands in Paid Other. The medium is the same. Only the source differs.
Google publishes the exact conditions and their order on its default channel group help page. Third-party guides disagree on how many channels exist, so treat that page as the only reference and re-check it before you change your naming rules.
Medium values GA4 recognises (email, cpc, organic, referral, social, affiliate, display, audio, sms, push)
Most Unassigned traffic comes from a medium that “makes sense” to your team but isn’t in Google’s lists. Here is how common combinations resolve under the current definitions:
| utm_source | utm_medium | Channel | Why |
|---|---|---|---|
| mailchimp | Medium email is accepted |
||
| mailchimp | Google also accepts e-mail, e_mail and e mail |
||
| mailchimp | newsletter | Unassigned | Unknown source plus an unlisted medium |
| cpc | Paid Search | Search source plus a paid medium | |
| partnersite | cpc | Paid Other | Paid medium from an unrecognised source |
| partnersite | paid_social | Paid Other | Medium starts with paid, but the source isn’t on the social list |
| anything | organic | Organic Search | Medium organic is accepted |
| blogname | referral | Referral | Mediums referral, app and link are accepted |
| campaignhub | social | Organic Social | Accepted social medium |
| campaignhub | fb | Unassigned | fb isn’t a social medium, and this source isn’t on the social list |
| campaignhub | ig | Unassigned | Same problem as fb |
| networkx | affiliate | Affiliates | Medium affiliate is accepted |
| networkx | banner | Display | banner, display, cpm, expandable and interstitial are accepted |
| podcastname | audio | Audio | Medium audio is accepted |
| twilio | sms | SMS | Medium sms is accepted |
| onesignal | web-push | Mobile Push Notifications | Medium ends with push |
| flyer | qr | Unassigned | qr isn’t listed anywhere |
| creatorname | influencer | Unassigned | influencer isn’t listed anywhere |
Some guides claim that banner and e-mail end up in Unassigned. Under Google’s current definitions they don’t. Check the live page rather than a blog post, including this one.
Source-category lists: why a misspelt source breaks the rules
Many rules don’t look at the medium at all. Instead, they check whether the source appears on Google’s category lists. There are separate lists for search sites, social sites, shopping sites and video sites, and the help page links to the full list.
For example, facebook / fb can still reach Organic Social because facebook is on the social list. If the source is misspelt or decorated, the safety net disappears:
utm_source=facebook → on the social list
utm_source=Facebook_Ads → not on the list
utm_source=facebok → not on the list
utm_source=ig_story → not on the list
Use plain, lowercase platform names for utm_source. Put extra detail, such as placement or audience, in utm_content or utm_campaign.
“Any UTM tag is better than none, so GA4 will sort it out.”
It won’t. If a tag matches no rule, the session lands in Unassigned. That’s arguably worse than Direct, because it looks tracked but reports nowhere useful.
The AI Assistant channel and its limits
Google added an AI Assistant channel on 13 May 2026. When the referrer matches Google’s internal list, GA4 sets the medium to ai-assistant and the campaign to (ai-assistant). Google’s documentation names ChatGPT, Gemini, Deepseek, Copilot and Grok.
- It isn’t retroactive. Sessions before the rollout keep their old channel, usually Referral or Unassigned.
- It rolled out gradually, so the start date may differ between properties.
- The full list isn’t published. Perplexity and smaller assistants are not guaranteed to be included.
- It depends on a referrer. Most ChatGPT clicks don’t send one, so many of those visits still rely on UTMs (see section 2).
- Check the exact label. Third-party sites write both “AI Assistant” and “AI Assistants”. Copy the exact label from the help page before you use it in filters or regex.
For a full setup covering assistants Google doesn’t recognise, see Track AI Referral Traffic in GA4.
Step 1: Run a 15-minute Unassigned and Direct audit in GA4
Before you rename UTMs or touch tags, find out what GA4 actually recorded. This audit tells you which of the later fixes (sections 5 to 8) you need.
Traffic acquisition report setup
- Go to Reports > Acquisition > Traffic acquisition.
- Set the date range to the last 90 days. Turn on Compare against the previous period.
- Make sure the table’s primary dimension is Session default channel group. Use the dropdown above the first column. Depending on your property, it may appear as “Session primary channel group”.
- Click Add filter and choose Session default channel group. Set the match type to exactly matches and the value to
Unassigned, then click Apply. - Click the + beside the dimension header and add Session source / medium as a secondary dimension.
- Sort by Sessions. Note the top 10 source/medium pairs.
- Repeat steps 4 to 6 with the value
Direct.
For Unassigned, you now have a list of the tags causing it. For Direct, you’ll almost always see (direct) / (none), so you need the Exploration below to dig further.
Explore: free-form table with source, medium, campaign and landing page
- Go to Explore, then choose Blank. Make sure the technique is Free form.
- Import these dimensions:
- Session default channel group
- Session source / medium
- Session campaign
- Landing page + query string
- Device category
- Hostname
- Date
- Import these metrics: Sessions, Engaged sessions and Key events.
- Add a filter on Session default channel group: matches regex
Unassigned|Direct. - Rows: Session source / medium, then Landing page + query string. Values: Sessions and Key events.
- Swap Hostname, Device category and Session campaign into the rows one at a time.
Hostname often reveals the cause quickly. Look for staging sites, checkout subdomains, payment gateways or a second domain that should be cross-domain linked.
Device category helps too. Direct traffic that is heavily mobile often comes from email apps and messengers that strip the referrer.
Decision rule: what each pattern means
| What you see | Likely cause | Go to |
|---|---|---|
| A named source/medium in Unassigned | Tagging problem: the medium or source doesn’t match any rule | Section 5 |
(not set) source or medium |
Session-identity or tag problem: events sent before config, or server-side hits with no session | Section 7 |
(direct) / (none) on blog or product pages |
Missing referrer: email apps, noreferrer, HTTP to HTTPS links, AI tools |
Section 6 |
(direct) / (none) on checkout or thank-you pages |
Payment gateway return or a cross-domain break | Section 8 |
source / medium landing page diagnosis
mailchimp / newsletter /spring-sale/?utm_medium=newsletter Tagging: rename medium to email
campaignhub / ig /new-arrivals/ Tagging: use instagram / social
creatorname / influencer /product/linen-shirt/ Tagging: map via custom channel group
(not set) / (not set) (not set) Identity: Measurement Protocol or pre-config event
(direct) / (none) /checkout/order-received/1842/?key=wc_... Payment return: check gateway and referral exclusions
(direct) / (none) /blog/ga4-guide/ Missing referrer: check email, messengers, AI tools
(direct) / (none) shop.example.com /cart/ Cross-domain break between domains
Spotting a spike versus a steady baseline
Move Date into the rows, or switch the visualisation to a line chart, and look at the shape of the data.
- A sudden step up on a specific date points to a change: a plugin or theme update, a new email platform, a consent banner change or a checkout migration. Line it up against your release log.
- A spike in a fixed window may be external. If Direct rose between roughly 8 and 15 October 2026 while ChatGPT-tagged sessions fell, that matches the ChatGPT UTM bug (see How to Track ChatGPT Search Traffic in GA4). Annotate that window, because the past data won’t be corrected.
- A steady, high baseline is structural. It usually means long-standing naming habits or a cross-domain setup that has never worked.
Some agencies quote “normal” ranges for Unassigned and Direct. These are opinions, not Google benchmarks. Compare your property against its own history, not someone else’s percentage.
If the audit turns up several overlapping causes and you’d like a second pair of eyes, you can book a free consultation.
Fix UTM naming that sends traffic to Unassigned
Most Unassigned traffic I see in audits comes from one source: UTM values that GA4’s rules don’t recognise. GA4 received a source and medium, but no channel definition matched them.
The good news is that this is the easiest cause to fix. You control your own tags, so you can rename them today and see cleaner data from tomorrow. Historical sessions stay as they are in the default group, but a custom channel group (section 9) can reclassify them.
Rename invented mediums
GA4’s default channels look for specific medium values. Email expects email. Affiliates expects affiliate. Paid channels look for mediums that contain cp or start with paid. Anything outside those patterns can fall through to Unassigned.
Before you rename anything, open Google’s channel definitions (Google Analytics Help) and check the current rule for each channel you use. Google updates this list, and third-party summaries often lag behind.
| Before (source / medium) | What happens | After (source / medium) | Expected channel |
|---|---|---|---|
| mailchimp / newsletter | No rule uses “newsletter”, so it lands in Unassigned | mailchimp / email | |
| fb / cpc | “cpc” matches the paid pattern, but “fb” may not be on the social source list, so it can land in Paid Other | facebook / paid_social | Paid Social |
| ig / story | Neither value matches a rule, so it lands in Unassigned | instagram / social | Organic Social |
| flyer / qr | No channel uses “qr”, so it lands in Unassigned | flyer / referral, or keep “qr” and catch it with a custom rule | Referral, or a custom “Offline / QR” channel |
| jane-doe / influencer | “influencer” matches nothing, so it lands in Unassigned | jane-doe / affiliate (paid commission) or instagram / social (organic post) | Affiliates or Organic Social |
| twilio / text | The SMS rule looks for “sms”, not “text” | twilio / sms | SMS |
Decision rule: if an honest GA4 medium fits, use it. If none fits, as with print and QR codes, keep one consistent custom value and handle it in a custom channel group. Don’t force traffic into a misleading channel just to empty Unassigned.
Lowercase everything and keep source spellings consistent
Treat UTM values as literal strings. In your reports, Facebook, facebook and m.facebook show up as three different sources. Each one also has to match Google’s source list on its own to reach the right channel.
Don’t rely on GA4 to normalise case or spelling for you. Pick one form and enforce it:
- Lowercase only:
facebook, notFacebookorFACEBOOK. - One name per platform:
facebook, neverfbin one campaign andfacebook.comin another. - Hyphens, not spaces:
spring-sale, notspring saleorspring%20sale. - No dates or IDs in source or medium. Put those in
utm_campaignorutm_content.
“UTMs on our own menu and banners help us see which internal promos work.”
They do the opposite. A UTM on an internal link starts a new session and overwrites the visitor’s real source. A visitor who arrived from Google Ads and then clicked your homepage banner becomes “homepage / banner”. Your ad loses the conversion. Use GA4 events, or select_promotion for ecommerce promos, to track internal clicks instead.
Tagging email, SMS, QR codes, influencers and partners
These are the channels where untagged or badly tagged links cause the most damage, because they often arrive with no referrer at all. Use a fixed pattern for each:
Email newsletter
https://example.com/winter-boots/?utm_source=mailchimp&utm_medium=email&utm_campaign=2026-11-winter-launch
SMS
https://example.com/offer/?utm_source=twilio&utm_medium=sms&utm_campaign=2026-11-flash-sale
QR code on a printed flyer (custom medium, caught by a custom channel rule)
https://example.com/menu/?utm_source=flyer-dhaka-store&utm_medium=qr&utm_campaign=2026-11-instore
Influencer paid on commission
https://example.com/serum/?utm_source=jane-doe&utm_medium=affiliate&utm_campaign=2026-q4-creators
Partner or reseller website
https://example.com/?utm_source=partnername&utm_medium=referral&utm_campaign=2026-partner-programme
A few practical rules:
- Generate links from one shared sheet, not by hand. Section 11 gives you a template.
- Point QR codes at a short redirect you control, so you can fix the tags later without reprinting.
- Give influencers and partners the finished URL. Don’t ask them to “add a UTM”.
- Click every tagged link once and confirm the session in GA4’s Realtime report before a campaign goes live.
Fix missing referrers that inflate Direct
Direct means GA4 received no source and no medium. That usually isn’t someone typing your URL. More often a real referrer existed but got lost somewhere between the click and your Google tag.
You can’t recover lost referrers for past sessions. You can stop the loss going forward, and you can tag the links you control so you no longer depend on the referrer at all.
Decision rule: if Direct rises on deep pages nobody would type, such as long product URLs, blog posts or filtered category pages, look for a lost referrer before you assume brand demand grew. Check this in Explore: rows for Landing page, a filter for Session default channel group exactly Direct, and a date comparison.
Email apps, messengers and PDFs
Desktop email clients, many mobile email apps, messaging apps such as WhatsApp, and links opened from PDFs or documents often send no referrer. The visit arrives as Direct.
- Tag every owned link. Newsletters, automated emails, order confirmations and email signatures should all carry UTMs.
- Tag links you share in messengers, for example
utm_source=whatsapp&utm_medium=socialfor a broadcast list. Check that your medium matches a current channel rule. - Tag links inside PDFs you publish, such as brochures, price lists and guides. If PDFs bring in search traffic, the PDF SEO guide covers how to structure them.
rel=noreferrer, HTTP-to-HTTPS links and redirects that strip parameters
These causes sit in the link or the server, so they need technical fixes.
| Cause | What happens | Fix |
|---|---|---|
rel="noreferrer" or referrerpolicy="no-referrer" on a partner’s link |
The browser sends no referrer | Ask the partner to use rel="noopener" instead where they can, or give them a tagged URL |
A secure (HTTPS) page links to your http:// URL |
Browsers don’t send a referrer on an HTTPS-to-HTTP downgrade, even if you then redirect to HTTPS | Ask high-value referrers to update links to https://. Make sure HTTPS is enforced site-wide |
| A redirect drops the query string | UTMs and gclid disappear, and the session can land in Direct |
Keep query strings intact on every 301 and 302 |
| Redirect chains (http → www → trailing slash) | Each hop is another chance to lose parameters | Collapse the chain into one redirect straight to the final URL |
Test redirects with a tagged URL. curl -sIL follows the whole chain and prints each Location header:
curl -sIL "http://example.com/winter-boots?utm_source=test&utm_medium=email&utm_campaign=redirect-check" | grep -i -E "^HTTP|^location"
Good result: the parameters survive every hop
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/winter-boots/?utm_source=test&utm_medium=email&utm_campaign=redirect-check
HTTP/2 200
Bad result: the query string is dropped
HTTP/1.1 301 Moved Permanently
Location: https://www.example.com/winter-boots/
HTTP/2 200
Run this for each variant: http and https, with and without www, with and without a trailing slash, plus any old URLs you redirected during a migration. If you recently moved domains, the site migration SEO guide covers redirect mapping in more depth.
WordPress and WooCommerce checks
On WordPress sites, parameters can be lost in several layers. Behaviour depends on your plugins, host and settings, so test your own setup rather than assuming:
- Redirect plugins. Open each rule and check how it handles query parameters. Many redirect tools have an option to pass, ignore or exact-match them. Then test with curl.
- Server rules. On Nginx,
return 301 https://www.example.com$request_uri;keeps the query string. A rule built on$uridrops it. On Apache, check forRewriteRulelines whose substitution ends in?, which discards the query string. - Trailing-slash and www redirects. These can come from WordPress itself, the host panel or a CDN. Find out which layer issues them.
- Caching and CDN layers. Ignoring parameters in the cache key is usually fine. Redirecting to a parameter-free URL is not. Test a cached page with a tagged URL in an incognito window.
- WooCommerce flows. Click a tagged product link, add to cart and check the session in Realtime or DebugView to confirm the source held.
AI assistants and apps that send no referrer
AI tools are now a visible source of Direct traffic. Most ChatGPT clicks arrive without a referrer, so utm_source=chatgpt.com is the main signal GA4 has.
From about 8 October 2026, ChatGPT links lost that UTM, and the visits landed in Direct. OpenAI called it a bug, and tags returned from about 15 October (Search Engine Journal). Gemini also added UTMs to cited links in early September 2026 and stopped around 28 September (Search Engine Roundtable).
- Annotate 8–15 October 2026 in every report and dashboard. The past data won’t be corrected.
- Don’t read a Direct spike as brand growth in that window, or a ChatGPT drop as lost visibility.
- In-app browsers in social and messaging apps often strip referrers too. Tag the links you post there.
For setting up AI source tracking properly, see how to track ChatGPT search traffic in GA4 and the wider AI referral traffic guide. If you’d like a second pair of eyes on your redirects and tagging, you can book a free consultation.
Fix tag order, consent mode and session-identity gaps
Not every Unassigned or Direct session comes from bad UTMs. Some come from your own setup: tags firing in the wrong order, a consent banner that drops the landing-page data, or server-side events that GA4 cannot attach to a session.
These causes are harder to spot because the campaign links look fine. The source data is lost inside your site, not before the visitor arrives.
Google tag must fire before event tags
GA4 reads the traffic source from the first hit of a session: the page URL (with its UTMs or gclid) and the referrer. That hit should come from the Google tag.
If an event tag fires first, the session can start in a broken state. Dolphin Analytics points to Google’s warning that custom events sent before the config can get batched with session_start. That can leave the session without a clean source and push it into Unassigned (Dolphin Analytics).
In Google Tag Manager, set the firing order like this:
- Open your container and go to Tags.
- Open your Google tag (the one with your G- measurement ID).
- Set its trigger to Initialization – All Pages.
- If you use a consent management platform (CMP), put its default-consent tag on Consent Initialization – All Pages.
- Check every GA4 event tag. None should use Initialization, Consent Initialization or a custom trigger that can fire before the page loads.
- Remove any hard-coded gtag.js snippet in your theme if GTM already loads the Google tag. Two Google tags can create duplicate or out-of-order hits.
Correct firing order in GTM
1. Consent Initialization – All Pages → CMP default consent
2. Initialization – All Pages → Google tag (G-XXXXXXX)
3. Container Loaded / DOM Ready / Page View → GA4 event tags
4. Clicks, form submits, custom events → GA4 event tags
On WordPress, also check plugins. A Site Kit tag, an ecommerce tracking plugin and a GTM container can all load GA4 on the same page. Pick one method and switch the others off.
Consent mode: what denied consent does to source data
Consent mode tells Google tags what the visitor has agreed to. There are two ways to run it, and they affect source data differently.
| Mode | What happens before consent | Effect on source data |
|---|---|---|
| Basic | Google tags are blocked until the visitor accepts. | No data at all for visitors who decline. For those who accept, the source depends on whether the landing-page URL and referrer are still available when the tag finally fires. |
| Advanced | Tags load with consent denied by default and send cookieless pings. | Google can use these pings for modelling. Visitors who accept are measured normally from that point. |
Google sets eligibility rules for modelled data. Check the current requirements in Google’s consent mode documentation rather than relying on numbers quoted in blogs.
The bigger risk for Unassigned and Direct is how the banner behaves:
- Banner reloads the page after “Accept”. The reloaded page has no external referrer. If the reload also drops the query string, your UTMs and gclid are gone. The session then shows as Direct or as a self-referral.
- Banner loads after the Google tag. The tag fires with no consent state, or fires twice, and the first hit may not carry the right source.
- Visitor clicks to a second page before accepting. In basic mode, the first tracked page is the second page, so the original referrer is lost.
Fixes to work through:
- Make the CMP update consent without a page reload. Most CMPs have a setting for this.
- Set default consent on Consent Initialization, before the Google tag.
- If you run ads, look at the
url_passthroughsetting in Google’s consent mode docs. It is designed to pass ad-click information through internal links when consent is denied. Confirm the current behaviour before enabling it.
gtag('consent', 'default', {
'ad_storage': 'denied',
'ad_user_data': 'denied',
'ad_personalization': 'denied',
'analytics_storage': 'denied'
});
// The CMP then calls gtag('consent', 'update', {...}) on accept, without reloading
To check consent state, open Tag Assistant, connect to your site with UTMs in the URL, and select an event. The Consent tab shows the on-page default and the update for each consent type. Accept the banner and confirm the page URL still contains your UTM parameters.
Measurement Protocol and server-side events without client_id or session_id
Measurement Protocol (MP) and server-side events are common for WooCommerce refunds, CRM conversions and offline orders. An MP event has no browser referrer and no landing page, so it depends on IDs to join an existing session.
Without a matching client_id, GA4 treats the event as a new user. Without a session_id inside the event params, it cannot attach the event to the browser session that holds the real source. Several guides report these events ending up in Unassigned (Scandiweb).
Capture both values in the browser at checkout. client_id comes from the _ga cookie. session_id comes from the _ga_XXXXXXX cookie for your measurement ID. Store them with the order, then send them with the event:
{
"client_id": "1234567890.1730540000",
"events": [
{
"name": "purchase",
"params": {
"session_id": "1730540123",
"engagement_time_msec": 100,
"transaction_id": "WC-10452",
"value": 89.00,
"currency": "GBP",
"debug_mode": true
}
}
]
}
Send it to the /mp/collect endpoint with your measurement ID and API secret. Use the /debug/mp/collect validation endpoint first; it returns errors in the payload format. Remove debug_mode once testing is done.
How to test with DebugView and Tag Assistant
- Open a private browser window and visit a landing page with test UTMs, for example
?utm_source=test&utm_medium=email&utm_campaign=debug. - In Tag Assistant, confirm the Google tag fires first and the first event is
page_viewwith your UTMs inpage_location. - In GA4, open Admin > Data display > DebugView and find your device.
- Check that
session_startandpage_viewarrive together, with no custom event before them. - Accept the consent banner and confirm no second
session_startappears. - Send your MP test event and confirm it appears in the same device stream.
The same checks matter for AI referral visits. If ChatGPT clicks still land in Direct after fixing tag order, read how to track ChatGPT search traffic in GA4.
Stop payment gateway self-referrals and cross-domain breaks
On WooCommerce stores, this is one of the most common reasons sales get credited to the wrong channel. The buyer arrives from Google Ads or organic search, pays on a gateway page, and returns to your thank-you page.
When they return, the browser may send the gateway as the referrer. GA4 can then start a new session with the gateway as the source, and the purchase goes to that session.
PayPal, Stripe, bKash, SSLCommerz and 3-D Secure pages taking credit for sales
You have this problem if you see any of these symptoms:
- Purchases credited to Referral, with sources like
paypal.com,checkout.stripe.comor ansslcommerz.comsubdomain. - A bank’s domain appearing as a referral source. 3-D Secure pages are often hosted by the card issuer, so these domains vary.
- Purchases in Direct or Unassigned that start on the order-received page, with no product or cart pages in the session.
- More sessions than expected landing on
/checkout/order-received/.
Mobile wallets add another twist. With bKash, the buyer may confirm payment in an app and return in a different browser or tab. That return can carry no referrer and no GA4 cookie, which shows up as Direct.
“PayPal sends us loads of customers. It’s one of our best referral sources.”
Usually it isn’t. PayPal processed the payment; it did not bring the buyer. Treat any payment domain in your referral report as a tracking problem, not a marketing channel.
To find the domains on your own store:
- Go to Reports > Acquisition > Traffic acquisition.
- Change the primary dimension to Session source.
- Add a filter for Session default channel group exactly matches Referral.
- Sort by key events or purchase revenue. Note every gateway, bank or payment domain.
- Repeat for Direct and Unassigned, adding Landing page as a secondary dimension. Look for the order-received page.
List unwanted referrals in GA4
Unwanted referrals tell GA4 to ignore the referrer when a visitor comes back from a listed domain. The session continues instead of restarting with the gateway as source.
- Go to Admin > Data streams and select your web stream.
- Click Configure tag settings. If you don’t see the option, click Show more.
- Open List unwanted referrals.
- Choose Referral domain contains as the match type.
- Add each gateway domain you found in your own report, one condition per domain.
- Save.
Example conditions (use the domains from YOUR report)
Referral domain contains paypal.com
Referral domain contains checkout.stripe.com
Referral domain contains sslcommerz.com
Referral domain contains bkash.com
Two points to keep in mind:
- The change only applies from the moment you save. Past purchases stay credited to the gateway. Annotate the date in your reports.
- It doesn’t extend the session. If a buyer takes longer than your session timeout on the payment page, a new session still starts. You can check the timeout in the same Configure tag settings screen under Adjust session timeout.
Don’t copy a long list of gateway domains from another site. Add only what appears in your data, and review the list when you add a new payment method.
Cross-domain measurement for separate checkout, booking or subdomain setups
Some stores send buyers to a different domain they own. Examples include a booking engine on a separate domain, a checkout on a regional domain, or a shop that moved during a WordPress domain migration with old links still in use.
Without cross-domain measurement, each domain sets its own _ga cookie. The visitor becomes two users, and the second domain records your first domain as a referrer.
- Make sure both domains use the same GA4 measurement ID.
- Go to Admin > Data streams > web stream > Configure tag settings > Configure your domains.
- Add every domain in the journey, for example
example.comandexample-booking.com. - Save, then click a link from one domain to the other.
- Check the destination URL contains a
_gl=parameter.
https://example-booking.com/book/?_gl=1*abc123*_ga*MTIzNDU2Nzg5MC4xNzMwNTQwMDAw*...
If _gl is missing on arrival, something is stripping it. Common causes:
- A server or plugin redirect that drops unknown query parameters.
- Forms that submit with POST to the other domain, where the parameter isn’t added automatically.
- Links opened by JavaScript after the tag decorated the original link.
- Caching or security rules that remove query strings.
Subdomains on the same root domain normally share the _ga cookie, so they rarely need cross-domain setup. If you see self-referrals from a subdomain, check that it uses the same measurement ID and that cookie settings haven’t been changed.
Keep your own domains off the unwanted referrals list. Adding them hides the referral line but doesn’t link the two cookies, so the visitor is still split into two users. Fix the link with cross-domain measurement instead.
WooCommerce checklist: verify each gateway with a test order
| Gateway or setup | Domain to check in your report | Fix | How to verify |
|---|---|---|---|
| PayPal (redirect checkout) | paypal.com and its subdomains | Add to unwanted referrals | Sandbox order; no new session_start on order-received in DebugView |
| Stripe Checkout (hosted page) | checkout.stripe.com | Add to unwanted referrals | Test-mode order; purchase appears in the same session as begin_checkout |
| Stripe on-page card fields | Usually none; check for 3-D Secure domains | Add only domains that appear | Test card that triggers 3-D Secure |
| SSLCommerz | sslcommerz.com subdomains | Add to unwanted referrals | Sandbox order; source on the purchase matches the landing source |
| bKash | bkash.com subdomains; also Direct on order-received | Unwanted referrals; check whether buyers return in a new browser | Test payment on mobile; watch for a second user in DebugView |
| Bank 3-D Secure pages | Issuer domains (vary by bank) | Add the specific domains you see | Review Referral report weekly after changes |
| Separate booking or checkout domain | Your own second domain as Referral | Configure your domains; same measurement ID | _gl present on arrival; one user across both domains |
For each test, open DebugView before you start. Land with test UTMs, add a product, pay, and return. You want one session_start at the beginning and a purchase event at the end, with nothing restarting in between.
Check the Traffic acquisition report 24–48 hours later to confirm the test order is credited to your test source. If gateway domains keep showing up, or purchases still land in Direct, a free consultation is a quick way to get the checkout tracking reviewed.
Build a custom channel group to catch what’s left
After you fix UTMs, referrers, tag order and gateways, a small amount of traffic may still land in the wrong channel. A custom channel group lets you sort that remainder in a way that fits your business without touching the original data.
Google keeps one default channel group for all properties, and nobody can edit it. Google describes Unassigned as “the value Analytics uses when there are no other channel rules that match the event data” (Google Analytics Help). A custom group adds your own rules on top of that.
Copy the default group first
Do not start from a blank group. If you copy the default group, every standard channel still works and you only add what is missing.
- Go to Admin > Data display > Channel groups.
- Open the default channel group and choose the option to copy it. You can also choose Create new channel group and rebuild the default rules, but copying is faster and leaves less room for error.
- Give it a clear name, such as “Channels – business view (v1, Nov 2026)”.
- Add your new channels and move them into the correct position in the list.
- Save, then open Reports > Acquisition > Traffic acquisition and switch the primary dimension to your custom channel group.
Two behaviours matter here:
- Custom channel groups apply to historical data. You can build one today and compare it against last year’s sessions.
- Sessions that match none of your custom rules fall back to the default group. Unassigned will only shrink if a rule actually matches the session.
Rule order matters. GA4 checks channels from the top of the list down, and the first match wins. A new channel placed below Referral will never receive referral sessions, because Referral claims them first.
Before you save, check the current channel list and rule definitions on Google’s page. Third-party guides disagree on how many default channels exist, so treat Google’s page as the source of truth (Google Analytics Help).
Add AI assistants not on Google’s list
GA4 added a default AI assistant channel in May 2026. When the referrer matches Google’s list, GA4 sets the medium to ai-assistant. Google’s documentation names ChatGPT, Gemini, Deepseek, Copilot and Grok. It does not publish the full list, so Perplexity and other tools are not guaranteed. Copy the exact channel label from Google’s help page, because third-party sites spell it in different ways.
A custom channel catches AI sources that Google’s list misses. One example condition set:
Channel name: AI Assistants (custom)
Condition 1: Session source matches regex (perplexity|claude|chatgpt|gemini|copilot)
OR
Condition 2: Session medium exactly matches ai-assistant
Position: above Referral and above Unassigned
Do not paste this regex in without testing it. First, open Traffic acquisition with Session source as the dimension, set a long date range, and export the full source list. Check that:
- Each AI source you actually receive is matched (for example
perplexity.ai,chatgpt.com,claude.ai). - Nothing unrelated is matched. A source or partner name that happens to contain “gemini” or “copilot” would be pulled in by mistake.
- The pattern still works if GA4 treats the regex as a full match in this field. If it does not match in testing, wrap it as
.*(perplexity|claude|chatgpt|gemini|copilot).*.
A custom channel cannot recover visits that arrived with no source at all. ChatGPT clicks from roughly 8–15 October 2026 lost their UTM and sent no referrer, so they sit in Direct permanently. For a fuller setup, see Track AI Referral Traffic in GA4 and How to Track ChatGPT Search Traffic in GA4.
Partner, QR and offline channels
Some traffic is real, intentional and has no matching default channel. Examples include QR codes on packaging, printed flyers, trade-show cards or affiliate-style partner links you track separately. These are good reasons to add a custom channel.
| Custom channel | Condition | Example UTM |
|---|---|---|
| QR & Print | Session medium exactly matches qr or print |
utm_source=flyer_dhaka&utm_medium=qr |
| Partners | Session medium exactly matches partner |
utm_source=supplierco&utm_medium=partner |
| Events | Session campaign contains event_ |
utm_campaign=event_sydney_expo_2026 |
Write these mediums into your UTM governance sheet (next section) so everyone uses the same values.
Check whether you can use it for attribution
By default, a custom channel group is a reporting view. Only some properties can set a custom group as the primary channel group used for attribution and key-event reporting, and limits on how many groups you can create depend on the property type. Check the current limits and eligibility in Google Analytics Help before you plan around this.
Mistake to avoid: hiding bad tagging
“We’ll just add a custom channel that maps ‘newsletter’, ‘e-mail’ and ‘Email_Blast’ into Email. Problem solved.”
That only fixes one report. The default channel group, attribution, Google Ads imports and anyone looking at an unfiltered report will still see Unassigned. If the cause is a typo or inconsistent naming, fix the UTMs at the source and use the standard medium (email).
Use this decision rule: a custom channel is for traffic types Google has no channel for, not for UTM mistakes.
Common mistakes and a troubleshooting table
Most Unassigned and Direct problems follow a few recognisable patterns. Use the table to match what you see in GA4 to the most likely cause, then confirm it before you change anything.
| Symptom | Likely cause | Fix |
|---|---|---|
| Sudden Unassigned spike the day a campaign launched | Non-standard utm_medium, such as newsletter, fb, ig, banner or influencer |
Filter Traffic acquisition by Unassigned and add Session source / medium. Correct the live links to standard mediums (email, paid_social, display and so on). |
(not set) source on purchase events |
Purchase sent server-side or via Measurement Protocol without client_id and session_id, or the event fires before the Google tag config |
Pass the browser’s client and session IDs with server-side purchases. Make sure the Google tag loads before any event tag on the thank-you page. |
| Direct spike on mobile only | Links shared in messengers and email apps that send no referrer, in-app browsers, or privacy features that strip parameters | Segment by device, browser and landing page. Add UTMs to links you share in WhatsApp, SMS and email. Accept that some untagged sharing will always show as Direct. |
| Referral from your own domain | A subdomain or second domain without cross-domain measurement, or pages missing the Google tag | Configure cross-domain measurement for every domain in the journey. Crawl for untagged templates. Add the domain to unwanted referrals only after the cross-domain setup is fixed. |
| PayPal, Stripe or a bank gateway as a top referral source | The visitor returns from the gateway and starts a new session credited to the gateway | Add the gateway domains to List unwanted referrals in your data stream’s tag settings, then check that purchases keep their original source. |
| AI traffic falling while Direct rises on the same pages | Lost UTM or referrer from the AI platform, such as the ChatGPT bug around 8–15 October 2026 | Compare AI and Direct landing pages over the same dates. Annotate the window. You cannot correct the past data, only explain it. |
Fixes that only move traffic to another wrong channel
Some “fixes” make Unassigned smaller but leave the data just as misleading. Watch for these:
- Tagging everything as
cpc. Mediums containing “cp” fall into paid channels such as Paid Other. Unassigned shrinks, but organic social and email now look like paid spend. - Setting
utm_medium=referralon newsletters. Email now looks like referral traffic, and Email performance appears to drop. - Adding UTMs to internal links or banners. Each click starts a new session with your own campaign as the source and overwrites the real source. Organic and paid lose credit for conversions.
- Listing your own domain as an unwanted referral to hide a cross-domain break. The Referral row disappears, but the underlying cookie or linker problem is still there.
- Catch-all custom channels. A rule such as “medium matches
.*” placed above Unassigned simply renames the problem.
A real fix puts sessions into the channel that matches how the visitor actually arrived. If you cannot explain why the new channel is correct, it is not a fix.
Changes only apply going forward
UTM corrections, unwanted referrals, cross-domain settings and tag-order fixes affect new data only. Sessions already collected keep their original channel. The only exception covered in this guide is custom channel groups, which re-sort historical data.
Record every change date so a future reader does not mistake a tracking fix for a marketing result:
2026-10-08 to 2026-10-15 ChatGPT links missing UTM; AI traffic undercounted, Direct inflated
2026-11-03 Newsletter UTMs changed from medium=newsletter to medium=email
2026-11-04 PayPal and Stripe added to unwanted referrals
2026-11-05 Custom channel group "business view v1" created
Add these as annotations in GA4 if your property supports them. Also add them to a shared change log and to your monthly report. The same habit makes Search Console reporting easier to trust too; see Rank Tracking Accuracy: A Search Console-First SEO Report.
Don’t judge yourself against generic benchmarks
“Unassigned should always be under X% and Direct under Y%.”
You will find agencies quoting “normal” ranges. These are opinions, not Google figures. Your healthy level depends on your traffic mix.
- A brand with heavy WhatsApp sharing, print QR codes or a loyal returning audience will naturally show more Direct.
- A store running many email and influencer campaigns will show Unassigned quickly if UTMs drift.
Use your own baseline instead. Compare the same months year on year, by device and landing page, with your annotations alongside. Investigate when the share moves sharply without a business reason.
If you have worked through every step and still cannot explain the numbers, book a free consultation and we can review the property together.
UTM governance template you can copy
Most Unassigned traffic is created by people, not by GA4. Someone types utm_medium=Newsletter, another person uses e-mail_blast, and a third tags an Instagram story with ig. A written UTM standard stops that drift before it reaches your reports.
The template below maps each common channel to values that GA4’s default channel group already recognises. Google can change those rules, so check the current list on the Google Analytics Help page for default channel groups before you publish the template to your team.
Allowed source and medium values
Use this as the single reference for anyone who builds links. If a value is not in the table, it is not allowed until the owner adds it.
| Channel | utm_source (allowed values) | utm_medium (allowed value) | utm_campaign format | Example | Owner |
|---|---|---|---|---|---|
Your email platform or list name, e.g. mailchimp, klaviyo, newsletter |
email |
yyyy-mm_product_offer | utm_source=klaviyo&utm_medium=email&utm_campaign=2026-11_winter-boots_20off |
Email marketer | |
| SMS | SMS provider, e.g. twilio, attentive |
sms |
yyyy-mm_product_offer | utm_source=twilio&utm_medium=sms&utm_campaign=2026-11_black-friday_early-access |
Email/CRM marketer |
| Paid social | facebook, instagram, linkedin, tiktok, pinterest |
paid_social |
yyyy-mm_product_offer | utm_source=facebook&utm_medium=paid_social&utm_campaign=2026-11_winter-boots_20off |
Paid media manager |
| Organic social posts | facebook, instagram, linkedin, tiktok, x |
social |
yyyy-mm_topic | utm_source=linkedin&utm_medium=social&utm_campaign=2026-11_ga4-audit-guide |
Social media manager |
| Affiliates | Affiliate network or partner ID, e.g. awin, impact |
affiliate |
yyyy-mm_programme | utm_source=awin&utm_medium=affiliate&utm_campaign=2026-11_evergreen |
Partnerships lead |
| QR codes and print | Placement, e.g. flyer, packaging, shopfront |
print (needs a custom channel rule) |
yyyy-mm_location_offer | utm_source=packaging&utm_medium=print&utm_campaign=2026-11_dhaka-store_reorder |
Marketing manager |
| Partners and co-marketing | Partner domain or name, e.g. supplier-blog |
referral |
yyyy-mm_partner_offer | utm_source=supplier-blog&utm_medium=referral&utm_campaign=2026-11_joint-webinar |
Partnerships lead |
| Podcasts (sponsored reads) | Show name, e.g. retail-weekly |
audio |
yyyy-mm_show_offer | utm_source=retail-weekly&utm_medium=audio&utm_campaign=2026-11_podcast_10off |
Marketing manager |
A few notes on the table:
- Paid social only works if the source is a recognised social site. GA4 checks the source against its social list and the medium against a paid pattern (mediums that contain “cp”, equal “ppc” or “retargeting”, or start with “paid”).
paid_socialstarts with “paid”, so it qualifies. - Do not let ad platforms fill the source dynamically unless you have checked the values they send. Hard-code
facebookorinstagramper ad set if the dynamic value produces short codes you have not tested. - Print and QR have no default channel.
utm_medium=printwill land in Unassigned unless you add a “Print & QR” rule to the custom channel group from the previous section. That is fine, as long as the rule exists. - Podcasts: Google’s Audio channel is built around the medium
audio. Confirm the current rule on the Help page above. For links in your own show notes, treat them as organic and agree one value with the owner.
“UTMs are just labels, so any wording is fine as long as we understand it.”
Not in GA4. The channel is decided by rules that match exact or patterned values. utm_medium=newsletter makes perfect sense to your team, but it matches no default rule, so the session goes to Unassigned.
Naming rules
Put these rules at the top of your builder sheet so nobody has to guess.
- Lowercase only. GA4 reports show
Emailandemailas separate rows, which splits your data even when the channel is correct. - No spaces. Use hyphens inside a word group and underscores between parts. Spaces become
%20or+in URLs and break filters. - One campaign format:
yyyy-mm_product_offer, for example2026-11_winter-boots_20off. The date first makes campaigns sort in order. - utm_content is for the creative or placement, for example
video-15s,carousel-2orheader-button. - utm_term is for paid keywords only. Do not use it for audiences, dates or creative names.
- Never tag internal links. UTMs on links between your own pages start a new session and overwrite the original source.
- Do not add UTMs to Google Ads links if auto-tagging is on. Let the
gcliddo the work unless you have a documented reason to override it.
A quick reference your team can paste into a brief:
utm_source = where the click came from (lowercase, no spaces)
utm_medium = how it arrived (only values from the allowed table)
utm_campaign = yyyy-mm_product_offer (e.g. 2026-11_winter-boots_20off)
utm_content = creative or placement (e.g. carousel-2)
utm_term = paid keyword only (leave empty for everything else)
Ownership, a builder sheet and a monthly check
Every channel needs one named owner. The owner approves new source values, keeps the table current and answers “which medium do I use?” questions. Without an owner, the template is out of date within a quarter.
Build the links in a shared Google Sheet rather than by hand:
- Use Data > Data validation with a dropdown for
utm_medium, pulled from the allowed table. - Add a check column that flags anything with capitals or spaces.
- Generate the final URL with a formula so nobody types the
?and&manually.
Columns: A = landing URL, B = source, C = medium, D = campaign, E = content
Valid campaign (TRUE/FALSE):
=REGEXMATCH(D2, "^[a-z0-9_-]+$")
Final URL (handles pages that already have a query string):
=A2 & IF(ISNUMBER(SEARCH("?", A2)), "&", "?")
& "utm_source=" & B2
& "&utm_medium=" & C2
& "&utm_campaign=" & D2
& IF(E2="", "", "&utm_content=" & E2)
Then block 10 minutes on the first working day of each month for this check:
| Check | Where in GA4 | What to do if it fails |
|---|---|---|
| Unassigned share by source/medium | Reports > Acquisition > Traffic acquisition, filter Session default channel group = Unassigned, secondary dimension Session source / medium | Fix the link at the source and tell the channel owner |
| New unknown mediums | Same report, sort by Session medium, compare with the allowed table | Correct the value, or add it to the table and the custom channel group |
| Gateway referrals | Filter Session source contains your payment providers (e.g. paypal, stripe) | Update the unwanted referrals list and retest checkout |
| Direct on deep pages | Landing page report filtered to Direct, look at product, blog and thank-you URLs | Look for untagged email, SMS or QR links and missing referrers |
| AI Assistant row | Traffic acquisition, default channel group | Confirm ChatGPT still arrives with utm_source=chatgpt.com; note any sudden shift into Direct |
Keep a short log of anything unusual. For example, the 8–15 October 2026 window, when ChatGPT links lost their UTM, should stay annotated so nobody reads that drop as a real loss of AI traffic. For the full AI setup, see how to track AI referral traffic in GA4 and how to track ChatGPT search traffic in GA4.
If you report GA4 alongside Search Console, the same discipline applies to your ranking data. The Search Console-first SEO report shows how to keep both views consistent.
Your next step is simple: run the 15-minute audit from Step 1, list every source/medium pair in Unassigned and Direct, and map each one to a row in this template. If you would like a second pair of eyes on your property or channel rules, you can book a free consultation.

Frequently Asked Questions
What does Unassigned mean in GA4?
Unassigned is the label GA4 uses when a session's source, medium and campaign values match none of its default channel rules. In most cases GA4 did receive tracking data, but in a format it couldn't classify. Home-made utm_medium values are the most common cause.
Is Unassigned traffic the same as Direct traffic?
No. Direct means GA4 received no source information at all, so the session is recorded as (direct) with medium (none) or (not set). Unassigned means GA4 received values but couldn't match them to a channel. You fix Direct by restoring referrers and tagging links. You fix Unassigned by correcting your UTM naming.
Why did my GA4 Direct traffic jump in October 2026?
From around 8 October 2026, ChatGPT links stopped adding utm_source=chatgpt.com. They still sent no referrer, so those visits were counted as Direct. OpenAI confirmed it was a bug, and tags started returning from about 15 October. Check whether Direct rose on the same landing pages that normally receive ChatGPT sessions.
Will GA4 reclassify past Unassigned or Direct sessions after I fix my tracking?
No. GA4 doesn't reprocess historical sessions, so data recorded before your fix keeps its original channel. Add an annotation or a reporting note for the affected dates. That way later comparisons aren't misread.
Can I add my own medium, such as qr or influencer, to GA4's default channels?
No. Google maintains one default channel group for all properties, and nobody can edit it. You can switch to a medium Google already recognises if it genuinely fits. Otherwise, keep your naming and create a custom channel group that maps those mediums to the channel you want.
Does GA4's AI Assistant channel capture all ChatGPT and Perplexity traffic?
Not reliably. The channel depends on a referrer matching Google's unpublished list, and most ChatGPT clicks send no referrer. Perplexity and smaller assistants aren't guaranteed to be on that list. The channel also doesn't apply to sessions recorded before it rolled out.
Why does the event-scoped channel show (not set) in GA4?
The event-scoped default channel group is used for key event attribution. GA4 shows (not set) for events that aren't key events, and that is expected behaviour. Use the session-scoped channel group when you audit Unassigned and Direct traffic.
Final Thoughts
Start with the 15-minute audit. Check Session source / medium for Unassigned sessions and Landing page + query string for Direct sessions. This shows you whether the problem is in your links, your tags or your referrer handling.
Next, standardise your UTMs. Use lowercase platform names for utm_source and mediums from Google’s list for utm_medium. Where a medium has no official equivalent, create a custom channel group to map it.
Add annotations for known breaks, such as the 8–15 October 2026 ChatGPT bug. Then re-check Google’s default channel group help page before you change any naming rules. If your Unassigned or Direct share rises again, treat it as a bug report and rerun the audit.
Want help applying this to your site? Run the free SEO check or book a free consultation with MD Harunur Rashid. Free SEO check · Book a free consultation



