2026-09-03
UTM Parameters Not Showing in GA4? Here's the Real Fix
You built the URL correctly. You can see utm_source, utm_medium, and utm_campaign sitting right there in the address bar when you test the link. But when you open GA4, the traffic shows up as (not set), "Direct," or "Unassigned" instead of your campaign name. You're not doing anything wrong with the URL itself — the parameters are almost certainly getting stripped or misattributed somewhere between the click and the report.
Why this happens
- Redirect chains are stripping the query string. This is the most common cause. If your link goes through a URL shortener, a link-in-bio tool, an email service provider redirect, or a landing page builder that 301/302s to your final domain, any hop that doesn't explicitly forward the query string will drop your UTMs before GA4 ever sees them.
- You're looking at the wrong scope of dimension. GA4 has both session-scoped (Session source / medium, Session campaign) and user-scoped (First user source / medium, First user campaign) dimensions. If a user already has an earlier session stored (even from weeks ago), GA4 may report the original first-user source instead of your new session's UTMs — depending on which dimension you dropped into your report or exploration.
- Processing latency. GA4 does not populate standard reports in real time. Acquisition data can take up to 24-48 hours to fully process and reconcile, especially for campaign-level dimensions. Checking too soon after a test click will show incomplete or "(not set)" data that later fills in correctly.
- Cross-domain or subdomain tracking gaps. If the click lands on one domain and then the user is bounced to another domain (checkout, booking, app subdomain) without cross-domain measurement configured, GA4 may start a new session and lose the original UTM context.
- Case sensitivity and parameter naming mismatches. GA4 treats
utm_Sourceandutm_sourceas different strings in some setups, and typos likeutm_campainwon't be recognized as a campaign parameter at all. - Ad blockers or consent mode blocking the hit before parameters can be captured, though this typically shows as missing sessions entirely rather than "(not set)" campaigns.
Fix, step by step
- Click your actual campaign link (not a shortened preview) and watch the browser's address bar through every redirect hop. If the query string disappears at any hop, that tool is the problem — check its "forward query parameters" or "pass-through parameters" setting.
- Open GA4's DebugView (in Configure) or use the Tag Assistant / GA4 debugger while clicking your live link, and confirm the
utm_source,utm_medium, andutm_campaignvalues appear on thepage_viewandsession_startevents. - In your GA4 report or Exploration, explicitly check which dimension you're using: Session source / medium vs. First user source / medium. Rebuild the report using Session-scoped dimensions if you're evaluating a specific campaign push, since first-user dimensions won't update on returning visitors.
- Wait at least 24-48 hours before judging results in standard reports. Use Realtime only to confirm the hit fired, not to confirm attribution accuracy.
- If the link crosses domains, confirm your domains are listed under Configure > Tag Settings > Configure your domains for cross-domain measurement in your GA4 web stream.
- Standardize parameter casing and spelling across every tool that generates your links (ad platforms, email tool, link shorteners). Lowercase everything — GA4's default channel grouping expects lowercase values for reliable matching.
- Re-test with a fresh, never-before-used URL and, ideally, an incognito browser session to rule out an existing first-user attribution overriding your new session.
Copy-paste UTM builder template
BASE URL STRUCTURE:
https://yourdomain.com/page?utm_source={source}&utm_medium={medium}&utm_campaign={campaign}&utm_content={content}&utm_term={term}
NAMING RULES (lowercase, no spaces, use hyphens):
utm_source -> platform or publisher (facebook, google, newsletter, partner-x)
utm_medium -> delivery method (cpc, email, social, referral, display)
utm_campaign -> campaign identifier (spring-sale-2024, q3-webinar-promo)
utm_content -> creative/variant (banner-a, text-link, video-v2)
utm_term -> paid keyword (if applicable)
EXAMPLE:
https://yourdomain.com/landing?utm_source=facebook&utm_medium=cpc&utm_campaign=spring-sale-2024&utm_content=carousel-v1
CHECKLIST BEFORE SENDING ANY LINK:
[ ] All parameters lowercase
[ ] No typos (utm_campaign, not utm_campain)
[ ] Tested link through every redirect hop, query string intact at final destination
[ ] Verified in GA4 DebugView before mass distribution
[ ] Logged in shared UTM tracking sheet to prevent duplicate/inconsistent naming
How to verify it worked
Send yourself the final live link (after all redirects), open it in an incognito window, and check GA4's DebugView for the session_start event with correct utm_source/utm_medium/utm_campaign values attached. Then wait 24-48 hours and pull a Session source / medium report filtered to that exact campaign name — if it shows your traffic instead of "(not set)," the chain is clean end to end.
Once GA4 is capturing UTMs correctly, the harder problem is turning that clean campaign data into a decision about what to do next. That's the gap Next Action Analyst is built to close — it takes your campaign exports and tells you which campaigns to scale, pause, or fix, instead of leaving you staring at another correctly-labeled report.
Next Action Analyst turns your campaign export into a prioritized list of changes to make tomorrow — with the numbers that justify each one.