Unencoded Spaces Breaking UTM Tracking: Fix in 60 Seconds
Spaces in UTM parameters causing data fragmentation? Replace with %20 or use underscores. Quick fix for broken campaign tracking.
Your GA4 campaign name shows up as "spring" instead of "spring sale 2024."
You check the URL. Unencoded spaces. Parameters truncated at the first space.
Here's the 60-second fix.
Table of contents
- The Problem
- Why It Happens
- Real Example
- The Fix
- Option 1: URL Encode (Recommended)
- Option 2: Use Underscores
- Option 3: Use Hyphens
- Option 4: Remove Spaces
- Quick Encoding Script
- Advanced: Build Complete Campaign URL
- How Browsers Handle Spaces
- Platform Behavior
- Prevention Rules
- Rule 1: Always Encode Values
- Rule 2: Use Consistent Naming Convention
- Rule 3: Validate Before Launch
- Testing Process
- Step 1: Build URL with Encoding (30 seconds)
- Step 2: Test in GA4 Real-Time (30 seconds)
- Bulk Fix Script (Python)
- Common Mistakes
- Mistake 1: Partial Encoding
- Mistake 2: Manual Copy-Paste
- Mistake 3: Spreadsheet Formula Errors
- Real-World Example: Email Campaign
- FAQ
- Should I use %20 or + for spaces?
- What if spaces are already in my live URLs?
- Do URL builders automatically encode spaces?
- Can I use tabs or newlines?
- Will this affect my historical data?
- How do I find all URLs with unencoded spaces?
- What about spaces in the domain or path?
- Can email clients fix this automatically?
- Does this affect mobile vs desktop differently?
- What other characters need encoding?
- Conclusion
🚨 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
The Problem
❌ BROKEN:
?utm_campaign=spring sale 2024
↑ ↑
Space breaks parsing
GA4 shows: "spring"
Missing: " sale 2024"
Spaces in URLs are illegal. Browsers and analytics platforms parse them as parameter terminators.
Why It Happens
URLs cannot contain unencoded spaces. When you include them:
- Browser truncates parameter at first space
- GA4 receives incomplete value
- Remaining text is ignored or misinterpreted
- Campaign names fragment across reports
Real Example
Company: SaaS startup
Campaign: "black friday sale"
Budget: $8,000 Google Ads
URL: ?utm_campaign=black friday sale
Result in GA4:
- Campaign name: "black"
- Expected: "black friday sale"
Impact:
- Could not identify which "black" campaign performed best
- All Black Friday variations merged under incomplete name
- $8,000 spend with corrupted attribution
60-second fix prevented this.
😰 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
The Fix
Option 1: URL Encode (Recommended)
❌ BEFORE:
?utm_campaign=spring sale 2024
✅ AFTER:
?utm_campaign=spring%20sale%202024
↑ ↑ ↑ ↑
Each space → %20
Result in GA4: "spring sale 2024" (exactly as intended)
Option 2: Use Underscores
❌ BEFORE:
?utm_campaign=spring sale 2024
✅ AFTER:
?utm_campaign=spring_sale_2024
↑ ↑ ↑
Spaces → underscores
Result in GA4: "spring_sale_2024" (readable, no encoding)
Option 3: Use Hyphens
❌ BEFORE:
?utm_campaign=spring sale 2024
✅ AFTER:
?utm_campaign=spring-sale-2024
↑ ↑ ↑
Spaces → hyphens
Result in GA4: "spring-sale-2024" (readable, SEO-friendly)
Option 4: Remove Spaces
❌ BEFORE:
?utm_campaign=spring sale 2024
✅ AFTER:
?utm_campaign=springsale2024
Result in GA4: "springsale2024" (compact, less readable)
Quick Encoding Script
// Encode UTM parameter value
function encodeUtmValue(value) {
return encodeURIComponent(value);
}
// Usage
const campaign = "spring sale 2024";
const encoded = encodeUtmValue(campaign);
console.log(encoded);
// Output: spring%20sale%202024
// Build full URL
const url = `https://site.com?utm_campaign=${encoded}`;
console.log(url);
// https://site.com?utm_campaign=spring%20sale%202024Advanced: Build Complete Campaign URL
function buildCampaignUrl(base, utms) {
const params = new URLSearchParams();
// Auto-encodes all values including spaces
params.set('utm_source', utms.source);
params.set('utm_medium', utms.medium);
params.set('utm_campaign', utms.campaign);
if (utms.content) params.set('utm_content', utms.content);
if (utms.term) params.set('utm_term', utms.term);
return `${base}?${params.toString()}`;
}
// Usage
const campaignUrl = buildCampaignUrl('https://site.com', {
source: 'google ads',
medium: 'paid search',
campaign: 'spring sale 2024'
});
console.log(campaignUrl);
// https://site.com?utm_source=google+ads&utm_medium=paid+search&utm_campaign=spring+sale+2024
// Note: URLSearchParams encodes spaces as + (valid alternative to %20)How Browsers Handle Spaces
Input URL:
https://site.com?utm_campaign=spring sale
Browser interpretation:
https://site.com?utm_campaign=spring
↑
Stops parsing here
Everything after space:
" sale" → Ignored or treated as separate parameter
Technical Explanation:
RFC 3986 (URL standard) defines spaces as reserved characters. Browsers must either:
- Truncate at the space (most common)
- Auto-encode the space (inconsistent across browsers)
- Reject the URL entirely (rare)
GA4 only receives what the browser sends, which is often the truncated value.
Platform Behavior
| Platform | Behavior with Unencoded Spaces |
|---|---|
| GA4 | Truncates at first space |
| May reject URL entirely | |
| Email clients | Often auto-encode (inconsistent) |
| URL shorteners | Usually reject or auto-encode |
| Truncates at space | |
| Truncates at space | |
| TikTok | May reject URL |
Prevention Rules
Rule 1: Always Encode Values
// ✅ CORRECT
const params = {
utm_source: 'facebook',
utm_campaign: 'spring sale'
};
const queryString = new URLSearchParams(params).toString();
// Automatically encodes: utm_campaign=spring+sale
// (Note: + is valid encoding for spaces in query strings)Rule 2: Use Consistent Naming Convention
✅ RECOMMENDED:
utm_campaign=spring_sale_2024 (underscores)
utm_campaign=spring-sale-2024 (hyphens)
utm_campaign=springsale2024 (no separators)
❌ AVOID:
utm_campaign=spring sale 2024 (spaces - must encode)
Rule 3: Validate Before Launch
function hasUnencodedSpaces(url) {
const queryString = url.split('?')[1] || '';
return queryString.includes(' ');
}
// Usage
const url = 'site.com?utm_campaign=spring sale';
if (hasUnencodedSpaces(url)) {
console.error('❌ URL contains unencoded spaces!');
// Fix automatically
const fixed = url.replace(/ /g, '%20');
console.log('✅ Fixed:', fixed);
}Testing Process
Step 1: Build URL with Encoding (30 seconds)
const baseUrl = 'https://site.com';
const params = {
utm_source: 'google',
utm_medium: 'cpc',
utm_campaign: 'spring sale 2024'
};
const url = `${baseUrl}?${new URLSearchParams(params).toString()}`;
console.log(url);
// https://site.com?utm_source=google&utm_medium=cpc&utm_campaign=spring+sale+2024Step 2: Test in GA4 Real-Time (30 seconds)
- Click URL
- Open GA4 → Realtime
- Check campaign name
- Verify complete value appears
Bulk Fix Script (Python)
import urllib.parse
def fix_unencoded_spaces(urls):
fixed_urls = []
for url in urls:
# Split URL into base and query
if '?' in url:
base, query = url.split('?', 1)
# Parse query parameters
params = urllib.parse.parse_qs(query)
# Rebuild with proper encoding
encoded_params = urllib.parse.urlencode(params, doseq=True)
fixed_url = f"{base}?{encoded_params}"
fixed_urls.append(fixed_url)
else:
fixed_urls.append(url)
return fixed_urls
# Usage
urls = [
"site.com?utm_campaign=spring sale 2024",
"site.com?utm_source=google ads&utm_medium=paid search"
]
fixed = fix_unencoded_spaces(urls)
for url in fixed:
print(url)Common Mistakes
Mistake 1: Partial Encoding
❌ WRONG:
?utm_campaign=spring%20sale 2024
↑ ↑ ↑
Encoded Space! (breaks parsing)
✅ RIGHT:
?utm_campaign=spring%20sale%202024
Mistake 2: Manual Copy-Paste
User copies: "spring sale 2024"
Pastes into: URL builder field
Builder adds: ?utm_campaign=spring sale 2024
Result: Broken (if builder doesn't auto-encode)
✅ FIX: Use builder with auto-encoding
Mistake 3: Spreadsheet Formula Errors
❌ WRONG Excel formula:
=A1&"?utm_campaign="&B1
If B1 = "spring sale", produces:
site.com?utm_campaign=spring sale (broken)
✅ RIGHT:
=A1&"?utm_campaign="&SUBSTITUTE(B1," ","_")
Produces:
site.com?utm_campaign=spring_sale (works)
Real-World Example: Email Campaign
Platform: Mailchimp Campaign: Black Friday 2024 Subject Line: "Black Friday Exclusive Sale"
Template merge tag:
<a href="{{website}}?utm_campaign={{campaign_name}}">Shop Now</a>Variables:
website = https://shop.com
campaign_name = Black Friday Sale
Result (BROKEN):
https://shop.com?utm_campaign=Black Friday Sale
GA4 received:
- Campaign: "Black" (truncated)
Fix the template:
<a href="{{website}}?utm_campaign={{campaign_name|urlencode}}">Shop Now</a>Or manually encode campaign_name:
campaign_name = Black_Friday_Sale
Result (FIXED):
https://shop.com?utm_campaign=Black_Friday_Sale
GA4 received:
- Campaign: "Black_Friday_Sale" (complete)
✅ 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
Join 2,847 marketers fixing their tracking daily
FAQ
Should I use %20 or + for spaces?
Both are valid. %20 works everywhere. + is valid in query strings but can be less reliable. Use %20 for consistency.
What if spaces are already in my live URLs?
Fix immediately. Update all placements. Consider 301 redirects from broken to fixed URLs to preserve any external links.
Do URL builders automatically encode spaces?
Most do, but not all. Always check the final URL before launch. Google Campaign URL Builder encodes automatically, but custom builders may not.
Can I use tabs or newlines?
No. Encode all whitespace: space → %20, tab → %09, newline → %0A. Never include literal whitespace in URLs.
Will this affect my historical data?
No. Historical data remains fragmented. The fix only affects future traffic from corrected URLs.
How do I find all URLs with unencoded spaces?
Export your campaign URLs to a spreadsheet, then use this formula to detect spaces:
=IF(ISNUMBER(FIND(" ",A1)),"Contains space","OK")
What about spaces in the domain or path?
Domain names cannot have spaces (invalid DNS). Path spaces should be encoded as %20 or replaced with hyphens for SEO-friendly URLs.
Can email clients fix this automatically?
Some email clients auto-encode URLs, but behavior is inconsistent. Never rely on auto-encoding—always encode manually before sending.
Does this affect mobile vs desktop differently?
No. Both mobile and desktop browsers follow the same URL encoding rules. Unencoded spaces break tracking on all devices.
What other characters need encoding?
Common characters requiring encoding: # → %23, & → %26, = → %3D, ? → %3F, / → %2F (when used in parameter values, not URL structure).
Conclusion
Unencoded spaces break UTM tracking. Fix: Replace spaces with %20 or underscores.
❌ utm_campaign=spring sale
✅ utm_campaign=spring%20sale
✅ utm_campaign=spring_sale
60 seconds to fix. Perfect tracking restored.
Technical Reference: URL Encoding Issues Validation Rule
✅ 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
Join 2,847 marketers fixing their tracking daily