troubleshootingUpdated 2025

UTM Parameters Not Detected in GA4: Troubleshooting Guide

UTMs in your URL but GA4 doesn't see them? Complete troubleshooting guide for missing campaign attribution.

8 min readtroubleshooting

Your campaign URL has UTM parameters. You can see them in the browser address bar. But Google Analytics 4 shows "Direct" traffic.

Your UTMs exist... but GA4 doesn't see them.

Here's the complete troubleshooting guide to diagnose and fix this problem.

🚨 Not sure what's breaking your tracking?

Run a free 60-second audit to check all 40+ ways UTM tracking can fail.

Scan Your Campaigns Free

✓ No credit card ✓ See results instantly

Step 1: Visual URL Inspection

Check for Missing Question Mark

The most common cause of undetected UTMs:

Code
❌ WRONG - Missing ?:
shop.com/products&utm_source=facebook

✅ CORRECT:
shop.com/products?utm_source=facebook
               ↑
          Required question mark

How to fix: Add ? before the first UTM parameter.

Check for Fragment Before Query

Second most common cause:

Code
❌ WRONG - # before ?:
shop.com/products#special?utm_source=facebook

✅ CORRECT:
shop.com/products?utm_source=facebook#special

How to fix: Move ? before #.

Check for Spaces in URL

Code
❌ WRONG - Spaces break parsing:
shop.com/products?utm_source=facebook campaign

✅ CORRECT:
shop.com/products?utm_source=facebook%20campaign

How to fix: URL-encode spaces as %20 or use hyphens.

😰 Is this your only tracking issue?

This is just 1 of 40+ ways UTM tracking breaks. Most marketing teams have 8-12 critical issues they don't know about.

• 94% of sites have UTM errors

• Average: $8,400/month in wasted ad spend

• Fix time: 15 minutes with our report

✓ Connects directly to GA4 (read-only, secure)

✓ Scans 90 days of data in 2 minutes

✓ Prioritizes issues by revenue impact

✓ Shows exact sessions affected

Get Your Free Audit Report

Step 2: Browser DevTools Inspection

Test URL Parsing

Open browser console and paste:

Javascript
const url = new URL('YOUR_CAMPAIGN_URL_HERE');
 
console.log('Full URL:', url.href);
console.log('Pathname:', url.pathname);
console.log('Search (query):', url.search);
console.log('Hash (fragment):', url.hash);
console.log('UTM Source:', url.searchParams.get('utm_source'));
console.log('UTM Medium:', url.searchParams.get('utm_medium'));
console.log('UTM Campaign:', url.searchParams.get('utm_campaign'));

Expected output (working UTMs):

Code
Full URL: https://shop.com/products?utm_source=facebook&utm_medium=cpc
Pathname: /products
Search (query): ?utm_source=facebook&utm_medium=cpc
Hash (fragment):
UTM Source: facebook
UTM Medium: cpc
UTM Campaign: null

Problem output (broken UTMs):

Code
Search (query): (empty string)
UTM Source: null
UTM Medium: null
UTM Campaign: null

If UTM parameters return null, GA4 cannot see them.

Check Network Tab

  1. Open DevTools → Network tab
  2. Visit your campaign URL
  3. Find the analytics request (collect?v=2 for GA4)
  4. Check if UTM parameters are in the request payload

Working GA4 request includes:

Code
ep.campaign_name=spring2024
ep.campaign_source=facebook
ep.campaign_medium=cpc

Broken GA4 request missing:

Code
(no campaign parameters)

Step 3: GA4 Configuration Check

Verify GA4 is Installed

Javascript
// Check if GA4 is loaded
console.log('dataLayer:', window.dataLayer);
console.log('gtag:', window.gtag);
 
// If both undefined, GA4 isn't installed

Check GA4 Measurement ID

Html
<!-- Verify this exists in your site's <head> -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'G-XXXXXXXXXX');
</script>

Test in GA4 Real-Time

  1. Open GA4 → Reports → Real-Time
  2. Visit your campaign URL in incognito mode
  3. Wait 30-60 seconds
  4. Check if session appears

If session appears without campaign data:

  • UTM parameters aren't reaching GA4
  • Check URL structure (Step 1-2)

If session doesn't appear at all:

  • GA4 not installed
  • Ad blocker active
  • Measurement ID wrong

Step 4: Common Technical Issues

Issue 1: URL Redirect Strips Parameters

Some redirect services drop query parameters:

Code
Original: short.link?utm_source=facebook
Redirects to: site.com/products (UTMs lost)

Test: Visit your short link and check if UTMs survive the redirect.

Fix: Use redirect services that preserve parameters, or add UTMs after the redirect.

Issue 2: JavaScript Navigation

Single-page apps (React, Vue, Angular) may not trigger GA4 on navigation:

Javascript
// ❌ WRONG - Doesn't trigger GA4 pageview
window.history.pushState({}, '', '/new-page?utm_source=x');
 
// ✅ CORRECT - Manually trigger GA4 pageview
window.history.pushState({}, '', '/new-page?utm_source=x');
gtag('event', 'page_view', {
  page_location: window.location.href,
  page_path: window.location.pathname,
  campaign_source: new URLSearchParams(window.location.search).get('utm_source'),
  campaign_medium: new URLSearchParams(window.location.search).get('utm_medium'),
  campaign_name: new URLSearchParams(window.location.search).get('utm_campaign'),
});

GDPR cookie banners may block GA4 until consent:

Code
User clicks campaign link → Lands on site → Cookie banner appears
→ User doesn't consent → GA4 never loads → UTMs not tracked

Solution: Ensure GA4 loads after consent, but capture UTMs in sessionStorage beforehand:

Javascript
// Save UTMs before GA4 loads
const params = new URLSearchParams(window.location.search);
['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'].forEach(key => {
  const value = params.get(key);
  if (value) sessionStorage.setItem(key, value);
});
 
// After consent, send to GA4
function onConsentGranted() {
  gtag('event', 'page_view', {
    campaign_source: sessionStorage.getItem('utm_source'),
    campaign_medium: sessionStorage.getItem('utm_medium'),
    campaign_name: sessionStorage.getItem('utm_campaign'),
  });
}

If you use UTM parameters on internal links, they overwrite the original source:

Code
1. User clicks Facebook ad: site.com/products?utm_source=facebook
2. User clicks internal link: site.com/about?utm_source=navbar
3. GA4 now attributes session to "navbar" (wrong!)

Fix: Never use UTM parameters on internal links.

Issue 5: Ad Blocker or Privacy Extensions

Browser extensions may block GA4:

  • uBlock Origin
  • Privacy Badger
  • Brave Browser shields

Test: Try in incognito mode without extensions.

Step 5: Server-Side Checks

Check Server Logs

Your server logs should show UTM parameters:

Code
✅ CORRECT:
GET /products?utm_source=facebook&utm_medium=cpc HTTP/1.1

❌ WRONG:
GET /products HTTP/1.1
(UTMs missing)

If UTMs aren't in server logs, they're being stripped before reaching your server (redirect issue, JavaScript issue, etc.).

Check Firewall/Security Rules

Some security tools strip query parameters:

  • Web Application Firewalls (WAF)
  • DDoS protection services
  • Security plugins

Test: Temporarily disable and check if UTMs work.

Step 6: Platform-Specific Issues

Facebook Ads

Facebook's link preview may cache old URLs without UTMs:

Fix: Clear Facebook's URL cache:

  1. Visit developers.facebook.com/tools/debug/
  2. Paste your campaign URL
  3. Click "Scrape Again"

Email Marketing (Mailchimp, Klaviyo)

Email clients may modify links:

Fix: Use plain text URLs instead of HTML link wrapping:

Html
❌ <a href="site.com?utm_source=email">Click</a>
✅ <a href="site.com?utm_source=email">site.com?utm_source=email</a>

Instagram may strip parameters from bio links:

Fix: Use a link-in-bio tool (Linktree, Beacons) that preserves UTMs.

Diagnostic Flowchart

Code
UTMs not detected?
│
├─ Can you see UTMs in browser address bar?
│  ├─ NO → URL structure wrong (missing ?, # before ?, etc.)
│  └─ YES → Continue
│
├─ Does browser console show UTMs in url.searchParams?
│  ├─ NO → URL parsing broken (check syntax)
│  └─ YES → Continue
│
├─ Is GA4 installed? (check source code)
│  ├─ NO → Install GA4
│  └─ YES → Continue
│
├─ Do GA4 network requests include UTMs?
│  ├─ NO → JavaScript issue, cookie consent, or ad blocker
│  └─ YES → Check GA4 Real-Time reports
│
└─ Session appears in GA4 without campaign data?
   └─ Internal link overwriting UTMs or delayed reporting

✅ Fixed this issue? Great! Now check the other 39...

You just fixed one tracking issue. But are your Google Ads doubling sessions? Is Facebook attribution broken? Are internal links overwriting campaigns?

Connects to GA4 (read-only, OAuth secured)

Scans 90 days of traffic in 2 minutes

Prioritizes by revenue impact

Free forever for monthly audits

Run Complete UTM Audit (Free Forever)

Join 2,847 marketers fixing their tracking daily

FAQ

How long does it take for UTMs to appear in GA4?

Real-Time reports: 30-60 seconds Standard reports: 24-48 hours

Can ad blockers prevent UTM tracking?

Yes. Ad blockers may block GA4 entirely, but UTM parameters themselves aren't blocked—the analytics script is.

Do UTMs work in incognito mode?

Yes. Incognito mode is perfect for testing UTMs without cookie interference.

What if only some UTM parameters are detected?

Check for special characters or encoding issues in the missing parameters.

Can I test UTMs without launching a campaign?

Yes. Create a test URL and visit it in incognito mode. Check GA4 Real-Time immediately.

Why do UTMs work on desktop but not mobile?

Check mobile-specific issues: AMP pages, app deep links, or mobile browser privacy settings.

Conclusion

UTM parameters not detected in GA4? Follow this systematic troubleshooting process:

  1. Visual check: Verify URL structure (?, #, spaces)
  2. Browser DevTools: Test URL parsing
  3. GA4 config: Verify installation and measurement ID
  4. Technical issues: Check redirects, JavaScript, cookies
  5. Platform-specific: Test in different browsers and platforms

Most issues are URL structure problems (missing ? or # before ?), fixable in seconds.


Technical Reference: Missing Query Separator Validation Rule

UTM

Get Your Free Audit in 60 Seconds

Connect GA4, run the scan, and see exactly where tracking is leaking budget. No credit card required.

Trusted by growth teams and agencies to keep attribution clean.