Fix Duplicate UTM Params: Remove Redundant Parameters in 3 Steps
Your URL has utm_source=facebook appearing twice. GA4 tracking is unpredictable.
Here's the 3-step fix to remove duplicates and restore reliable 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
❌ DUPLICATE:
?utm_source=facebook&utm_medium=cpc&utm_source=instagram
↑ ↑
Same parameter twice
Result: GA4 behavior unpredictable
Quick Fix (3 Steps)
Step 1: Find Which Value to Keep (60 seconds)
Look at your URL:
?utm_source=facebook&utm_medium=cpc&utm_source=instagram
Ask: Which value is correct?
- facebook (first occurrence)?
- instagram (last occurrence)?
- Neither (need different value)?
Decision determines which to keep
Step 2: Remove Duplicate (30 seconds)
❌ BEFORE:
?utm_source=facebook&utm_medium=cpc&utm_source=instagram
✅ AFTER (keeping first):
?utm_source=facebook&utm_medium=cpc
✅ AFTER (keeping last):
?utm_source=instagram&utm_medium=cpc
Manual edit: Delete the incorrect parameter occurrence.
Step 3: Verify in GA4 Real-Time (30 seconds)
1. Visit corrected URL
2. Open GA4 → Realtime
3. Check "Traffic acquisition"
4. Verify source shows single correct value
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
Automated Fix (JavaScript)
For Single URL
function removeDuplicateUtm(url, keepFirst = true) {
const urlObj = new URL(url);
const params = new URLSearchParams();
const seen = new Set();
for (const [key, value] of urlObj.searchParams.entries()) {
if (!seen.has(key)) {
params.append(key, value);
seen.add(key);
} else if (!keepFirst) {
// Update to last value if keepFirst=false
params.set(key, value);
}
}
urlObj.search = params.toString();
return urlObj.toString();
}
// Usage
const broken = 'https://site.com?utm_source=facebook&utm_campaign=spring&utm_source=instagram';
// Keep first occurrence
console.log(removeDuplicateUtm(broken, true));
// Output: https://site.com?utm_source=facebook&utm_campaign=spring
// Keep last occurrence
console.log(removeDuplicateUtm(broken, false));
// Output: https://site.com?utm_source=instagram&utm_campaign=springFor Multiple URLs (Batch Processing)
function batchFixDuplicates(urls) {
return urls.map(url => {
try {
return removeDuplicateUtm(url, true);
} catch (error) {
console.error(`Failed to process: ${"{"}{"{"}url{"}"}{"}"}}`, error);
return url; // Return original if fix fails
}
});
}
// Usage
const brokenUrls = [
'site.com?utm_source=fb&utm_source=ig',
'site.com?s=email&utm_campaign=a&utm_campaign=b',
'site.com?utm_medium=cpc&other=x&utm_medium=paid'
];
const fixed = batchFixDuplicates(brokenUrls);
console.log(fixed);
// All duplicates removed, first occurrence keptBrowser Console Quick Fix
// Paste this in browser console when on the broken URL
(function() {
const url = new URL(window.location.href);
const params = new URLSearchParams();
const seen = new Set();
for (const [key, value] of url.searchParams.entries()) {
if (!seen.has(key)) {
params.append(key, value);
seen.add(key);
}
}
url.search = params.toString();
window.location.href = url.toString();
})();
// Automatically redirects to cleaned URLPlatform-Specific Fixes
Google Ads
Problem: Value Tracking template duplicates UTMs
Fix:
1. Final URL: https://site.com?utm_source=google&utm_medium=cpc
2. Tracking template: `{"{"}{"{"}lpurl{"}"}{"}"}}`?gclid=`{"{"}{"{"}gclid{"}"}{"}"}}`
(Don't add utm_source again in tracking template)
✅ Result: site.com?utm_source=google&utm_medium=cpc&gclid=123
Facebook Ads
Problem: URL Parameters field duplicates existing UTMs
Fix:
1. Destination URL: https://site.com?utm_source=facebook
2. URL Parameters: utm_medium=paid&utm_campaign=spring
(Don't repeat utm_source)
✅ Result: site.com?utm_source=facebook&utm_medium=paid&utm_campaign=spring
Email Platforms (Mailchimp, Klaviyo)
Problem: Template concatenation duplicates parameters
Fix:
Check if base URL has UTMs before adding:
❌ WRONG:
<a href="{`{"{"}{"{"}landing_page{"}"}{"}"}}`}?utm_source=email&utm_campaign={"{"}{"{"}campaign_name{"}"}{"}"}}">
If landing_page already has utm_source, you get duplicates
✅ RIGHT:
Use platform's merge tags correctly, or ensure landing_page is clean base URL
Common Patterns
Pattern 1: First Correct, Second Wrong
?utm_source=facebook&utm_campaign=spring&utm_source=social
Fix: Remove second utm_source
Result: ?utm_source=facebook&utm_campaign=spring
Pattern 2: First Wrong, Second Correct
?utm_source=website&utm_campaign=spring&utm_source=facebook
Fix: Remove first utm_source
Result: ?utm_source=facebook&utm_campaign=spring
Or manually reorder:
?utm_source=facebook&utm_campaign=spring
Pattern 3: Both Wrong
?utm_source=abc&utm_campaign=spring&utm_source=xyz
Fix: Remove both, add correct value
Result: ?utm_source=facebook&utm_campaign=spring
Pattern 4: Multiple Duplicates
?utm_source=a&utm_source=b&utm_campaign=x&utm_campaign=y&utm_source=c
Fix: Remove all duplicates systematically
Result: ?utm_source=a&utm_campaign=x
(Keeps first occurrence of each)
Validation After Fix
// Verify no duplicates remain
function verifyNoDuplicates(url) {
const params = new URL(url).searchParams;
const counts = {};
for (const [key] of params.entries()) {
counts[key] = (counts[key] || 0) + 1;
}
const duplicates = Object.entries(counts)
.filter(([, count]) => count > 1)
.map(([key]) => key);
if (duplicates.length > 0) {
console.error('❌ Duplicates still exist:', duplicates);
return false;
}
console.log('✅ No duplicates found');
return true;
}
// Usage
const url = 'https://site.com?utm_source=facebook&utm_campaign=spring';
verifyNoDuplicates(url);
// ✅ No duplicates foundPrevention (After Fixing)
1. Use URLSearchParams .set() Method
// ✅ CORRECT: .set() replaces instead of duplicating
const url = new URL('https://site.com');
url.searchParams.set('utm_source', 'facebook');
url.searchParams.set('utm_medium', 'cpc');
// If you call .set() again with same key, it replaces:
url.searchParams.set('utm_source', 'instagram'); // Replaces 'facebook'
console.log(url.toString());
// https://site.com?utm_source=instagram&utm_medium=cpc2. Check Before Adding
// ✅ CORRECT: Check existence before appending
function safeAddUtm(url, key, value) {
const urlObj = new URL(url);
if (urlObj.searchParams.has(key)) {
console.warn(`${"{"}{"{"}key{"}"}{"}"}} already exists, replacing...`);
urlObj.searchParams.set(key, value);
} else {
urlObj.searchParams.append(key, value);
}
return urlObj.toString();
}3. Validate Before Launch
// Add to pre-launch checklist
function preLaunchCheck(url) {
const checks = [];
// Check for duplicates
const params = new URL(url).searchParams;
const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
utmParams.forEach(param => {
const count = params.getAll(param).length;
if (count > 1) {
checks.push(`❌ Duplicate ${"{"}{"{"}param{"}"}{"}"}} (${"{"}{"{"}count{"}"}{"}"}} occurrences)`);
} else if (count === 1) {
checks.push(`✅ ${"{"}{"{"}param{"}"}{"}"}} OK`);
}
});
return checks;
}✅ 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
Which value should I keep if both are different?
Choose the value that matches your campaign intent. If utm_source=facebook and utm_source=instagram, keep the one matching where the link is actually placed.
Can I use regex to fix duplicates?
URLSearchParams is safer. Regex can break if URL structure varies.
What if the duplicate has the same value?
?utm_source=facebook&utm_campaign=spring&utm_source=facebook
Still remove one. Having duplicates, even with same value, can cause parsing inconsistencies.
How do I prevent this in URL builders?
Use .set() instead of .append() in URLSearchParams. .set() automatically replaces duplicates.
Conclusion
Fix duplicate UTM parameters in 3 steps:
- Identify which value to keep (first, last, or neither)
- Remove duplicate parameter
- Verify in GA4 Real-Time
Prevention: Use URLSearchParams.set() method, which replaces instead of duplicating.
url.searchParams.set('utm_source', 'facebook'); // Never creates duplicatesTechnical Reference: Duplicate UTM Parameters Validation Rule