troubleshootingUpdated 2025

Fix Plus Sign UTM Error: Replace + with %2B or Alternative

+ in UTM causing inconsistent tracking? Quick fix guide to encode plus signs correctly or use alternatives for reliable campaign data.

7 min readtroubleshooting

Your UTM has a + sign. GA4 shows inconsistent values across sessions.

Here's the 3-step fix to encode + correctly and restore consistent tracking.

🚨 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

Code
❌ INCONSISTENT:
?utm_campaign=google+ads

GA4 shows randomly:
- "google ads" (+ decoded as space)
- "google+ads" (+ kept as +)

One URL, two different campaign values

Quick Fix (3 Steps)

Step 1: Decide on Approach (30 seconds)

Code
Choose one:

Option A: Encode + as %2B
→ Preserves + symbol in GA4

Option B: Replace with hyphen
→ Simpler, no encoding

Option C: Remove +
→ Shortest option

Step 2: Apply Fix (60 seconds)

Option A: Encode as %2B

Code
❌ BEFORE:
?utm_campaign=google+ads

✅ AFTER:
?utm_campaign=google%2Bads

GA4 shows: "google+ads"

Option B: Replace with Hyphen

Code
❌ BEFORE:
?utm_campaign=google+ads

✅ AFTER:
?utm_campaign=google-ads

GA4 shows: "google-ads"

Option C: Remove +

Code
❌ BEFORE:
?utm_campaign=google+ads

✅ AFTER:
?utm_campaign=googleads

GA4 shows: "googleads"

Step 3: Test (30 seconds)

Code
1. Visit fixed URL
2. Check browser console:
   new URL(location.href).searchParams.get('utm_campaign')
3. Verify consistent value
4. Check GA4 Real-Time

Done.

😰 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

Why + Causes Inconsistency

The + symbol has dual meaning in URLs:

Historical usage: + represented spaces in early URL encoding (before %20 became standard)

Modern ambiguity: Some systems decode + as space, others keep it as literal +

Result: Same URL produces different GA4 values depending on:

  • Browser version
  • Platform click redirects
  • Server-side URL processing
  • Client-side JavaScript parsing

This creates data fragmentation where identical campaign URLs report under multiple campaign names.

Automated Fix Script

Javascript
function fixPlusSign(url, method = 'encode') {
    const urlObj = new URL(url);
 
    ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'].forEach(key => {
        let value = urlObj.searchParams.get(key);
 
        if (value && value.includes('+')) {
            switch(method) {
                case 'encode':
                    // Encode + as %2B
                    value = value.replace(/\+/g, '%2B');
                    break;
                case 'hyphen':
                    // Replace + with -
                    value = value.replace(/\+/g, '-');
                    break;
                case 'remove':
                    // Remove + entirely
                    value = value.replace(/\+/g, '');
                    break;
            }
 
            urlObj.searchParams.set(key, value);
        }
    });
 
    return urlObj.toString();
}
 
// Usage
const broken = 'site.com?utm_campaign=google+ads';
 
console.log(fixPlusSign(broken, 'encode'));
// site.com?utm_campaign=google%2Bads
 
console.log(fixPlusSign(broken, 'hyphen'));
// site.com?utm_campaign=google-ads
 
console.log(fixPlusSign(broken, 'remove'));
// site.com?utm_campaign=googleads

Common Scenarios & Fixes

Scenario 1: Product Names

Code
Product: C++ Programming

❌ INCONSISTENT:
utm_content=C++

✅ FIX Option 1:
utm_content=C%2B%2B
→ GA4: "C++"

✅ FIX Option 2:
utm_content=cpp
→ GA4: "cpp"

Scenario 2: Brand Names

Code
Brand: Google+

❌ INCONSISTENT:
utm_source=google+

✅ FIX Option 1:
utm_source=google%2B
→ GA4: "google+"

✅ FIX Option 2:
utm_source=googleplus
→ GA4: "googleplus"

Scenario 3: Multiple + Symbols

Code
Campaign: C++ for C# Developers

❌ INCONSISTENT:
utm_campaign=c++for-c#-devs

✅ FIX:
utm_campaign=cpp-for-csharp-devs
→ Simple, readable, no encoding

Scenario 4: Mathematical Operators

Code
Campaign: 1+1 Sale

❌ INCONSISTENT:
utm_campaign=1+1_sale

✅ FIX Option 1:
utm_campaign=1%2B1_sale
→ GA4: "1+1_sale"

✅ FIX Option 2:
utm_campaign=bogo_sale
→ More descriptive anyway

Bulk Fix Script

Javascript
// Fix multiple URLs at once
function bulkFixPlusSign(urls, method = 'encode') {
    return urls.map(url => {
        try {
            return fixPlusSign(url, method);
        } catch (error) {
            console.error(`Failed to fix: ${url}`, error);
            return url;
        }
    });
}
 
// Usage
const urls = [
    'site.com?utm_campaign=google+ads',
    'site.com?utm_source=bing+search',
    'site.com?utm_content=c++'
];
 
const fixed = bulkFixPlusSign(urls, 'encode');
console.log(fixed);
// All + encoded as %2B

Platform-Specific Application

Code
Tracking Template:
{lpurl}?utm_campaign=google%2Bads&gclid={gclid}
                          ↑
                    Encode + as %2B

Facebook Ads

Code
URL Parameters:
utm_source=facebook&utm_campaign=product%2Bads
                                      ↑
                                Encode + as %2B

Microsoft Ads

Code
Tracking Template:
{lpurl}?utm_campaign=bing%2Bsearch&msclkid={msclkid}
                         ↑
                   Encode + as %2B

Email HTML

Html
<a href="site.com?utm_campaign=product%2Bpromo&utm_source=email">
    Shop Now
</a>

Validation After Fix

Javascript
function validatePlusFix(url) {
    const urlObj = new URL(url);
    const rawQuery = url.split('?')[1] || '';
 
    // Check if any unencoded + remains in UTM values
    const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
 
    const issues = utmParams
        .filter(param => {
            const paramPattern = new RegExp(`${param}=([^&]*)`);
            const match = rawQuery.match(paramPattern);
            return match && match[1].includes('+') && !match[1].includes('%2B');
        })
        .map(param => ({
            parameter: param,
            issue: 'Contains unencoded +'
        }));
 
    return {
        valid: issues.length === 0,
        issues
    };
}
 
// Usage
const url = 'site.com?utm_campaign=google%2Bads';
const result = validatePlusFix(url);
 
if (result.valid) {
    console.log('✅ All + signs properly encoded');
} else {
    console.log('❌ Issues found:', result.issues);
}

Decision Matrix

Original ValueMethodResultWhen to Use
google+adsEncodegoogle%2BadsNeed to preserve +
google+adsHyphengoogle-adsDon't need +
google+adsRemovegoogleadsShort URLs needed
C++EncodeC%2B%2BBrand/product name
C++ReplacecppAbbreviation OK
1+1 saleEncode1%2B1_saleMath expression
1+1 saleReplacebogo_saleClearer meaning

Testing Checklist

Code
After fixing:

✅ Visual check
   URL contains %2B (or alternative), not raw +

✅ Browser test
   new URL('url').searchParams.get('utm_campaign')
   Shows consistent value

✅ Cross-browser test
   Chrome, Firefox, Safari, Mobile
   All show same value

✅ GA4 Real-Time test
   Campaign appears with expected value
   No data fragmentation

✅ Historical comparison
   Compare to past campaign names
   Ensure no duplicates created

Real-World Example: Tech Product Launch

Company: Online learning platform Product: "C++ Mastery Course" Campaign: Google Ads + Facebook Ads Budget: $12,000

Broken URLs:

Code
Google: site.com/cpp?utm_campaign=c++_mastery&utm_source=google
Facebook: site.com/cpp?utm_campaign=c++_mastery&utm_source=facebook

Result in GA4:

  • Campaign variations showing as:
    • "c _mastery" (+ decoded as spaces)
    • "c++_mastery" (+ preserved)
  • Data split across 2 campaign names
  • Unable to calculate true ROI

Fixed URLs (2 minutes):

Code
Google: site.com/cpp?utm_campaign=cpp_mastery&utm_source=google
Facebook: site.com/cpp?utm_campaign=cpp_mastery&utm_source=facebook

Result:

  • Single unified campaign: "cpp_mastery"
  • Accurate ROI calculation
  • Clear attribution across platforms

✅ 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

Should I always encode + as %2B?

If you need literal + in GA4, yes. Otherwise, consider simpler alternatives (hyphen, remove). For brand names like Google+ or product names like C++, encoding preserves the original branding.

What if + appears multiple times?

Encode or replace ALL occurrences:

Javascript
value.replace(/\+/g, '%2B') // All + → %2B

Never partially encode—this creates even more fragmentation.

Will this break existing campaigns?

If changing mid-campaign, you'll create new campaign value in GA4. Historical data remains under old value. Better to fix before launch. For active campaigns, consider finishing the campaign with existing URLs and fixing for next campaign.

Can I use + for spaces?

Not recommended. Use %20 or underscores for better reliability. The + symbol's dual meaning (space vs literal plus) causes too much inconsistency across platforms.

How do I find all URLs with unencoded + signs?

Export campaign URLs, use this regex pattern:

Javascript
const hasUnencodedPlus = url.match(/[?&]utm_[^=]+=([^&]*\+[^&]*)/);

Or in Google Sheets:

Code
=IF(ISNUMBER(SEARCH("+",A1)),"Contains +","OK")

Does this affect URL shorteners?

Most URL shorteners (Bitly, TinyURL) handle encoding automatically, but it's safer to encode before shortening to ensure consistency.

What about + in the domain or path?

Domain names cannot contain +. In URL paths, + should be avoided or encoded as %2B for consistency.

Can email platforms handle + signs correctly?

Email platforms vary. Some auto-encode, others don't. Always manually encode to ensure consistency across Mailchimp, Klaviyo, SendGrid, etc.

How does this interact with server-side tracking?

Server-side tracking (via Measurement Protocol) requires consistent encoding. If your server decodes + as space but GA4 keeps it literal, you'll have duplicate sessions. Always encode as %2B for server-side implementations.

What if my CMS or marketing platform adds + automatically?

Check your platform's URL encoding settings. Disable automatic + insertion if possible. If not, use the JavaScript fix script to clean URLs before they reach GA4.

Conclusion

Fix + in UTM parameters in 3 steps:

  1. Choose approach: encode, replace, or remove
  2. Apply fix using script or manual edit
  3. Test in browser and GA4
Code
❌ utm_campaign=google+ads (inconsistent)
✅ utm_campaign=google%2Bads (encoded)
✅ utm_campaign=google-ads (alternative)

Encode + as %2B for consistent tracking across all platforms.


Technical Reference: Plus Sign in Value 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

Run Complete UTM Audit (Free Forever)

Join 2,847 marketers fixing their tracking daily

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.