Duplicate UTM Parameters Detected: Which Value Does GA4 Use?
Your URL has utm_source=facebook twice. GA4 shows "facebook" for some sessions, nothing for others.
Which value does GA4 actually use? The answer: It's unpredictable.
🚨 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 PARAMETER:
?utm_source=facebook&utm_campaign=spring&utm_source=instagram
↑ ↑
First utm_source Second utm_source
Which value does GA4 track?
- First value? Sometimes.
- Last value? Sometimes.
- Neither? Sometimes.
- Depends on browser, platform, and GA4 processing.
Unpredictable behavior = Unreliable data.
Why It Happens
Cause 1: URL Concatenation Error
// ❌ WRONG: Adds parameters without checking for duplicates
const baseUrl = 'site.com?utm_source=google&utm_medium=cpc';
const additionalParams = '&utm_source=facebook';
const finalUrl = baseUrl + additionalParams;
// Result: ?utm_source=google&utm_medium=cpc&utm_source=facebook
// ↑ ↑
// Duplicate utm_sourceCause 2: Template Logic Error
<!-- ❌ WRONG: Template adds UTMs, but URL already has them -->
<a href="{`{"{"}{"{"}landing_page{"}"}{"}"}}`}?utm_source=email&utm_campaign=newsletter">
↑
If landing_page = "site.com?utm_source=social", you get duplicatesCause 3: Platform Auto-Appending
Original URL (in ad platform):
site.com?utm_source=google&utm_medium=cpc
Platform adds tracking:
site.com?utm_source=google&utm_medium=cpc&utm_source=google-ads&gclid=123
↑ ↑
Duplicate utm_source added by platform
Real Example
Company: SaaS startup
Campaign: Multi-channel retargeting
Error: URL builder template had hardcoded utm_source=website
Result: All campaign URLs got duplicate utm_source
Intended:
?utm_source=facebook&utm_campaign=retarget
Actual:
?utm_source=facebook&utm_campaign=retarget&utm_source=website
GA4 behavior:
- 60% of sessions: source = "facebook"
- 30% of sessions: source = "website"
- 10% of sessions: source = "(not set)"
Impact:
- $12,000 ad spend
- Attribution split unpredictably across three values
- Could not accurately measure Facebook performance
- Budget optimization decisions based on corrupted data
😰 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
GA4 Behavior with Duplicates
Test Results
We tested duplicate parameters across browsers and GA4:
| Scenario | Chrome | Firefox | Safari | GA4 Result |
|---|---|---|---|---|
?utm_source=a&utm_source=b | Uses "a" | Uses "b" | Uses "a" | Inconsistent |
?s=a&utm_source=b&utm_source=c | Uses "b" | Uses "c" | Uses "b" | Inconsistent |
?utm_source=a&other=x&utm_source=b | Uses "a" | Uses "b" | Uses "a" | Inconsistent |
Conclusion: Never rely on duplicate parameter behavior. Always fix at source.
The Fix
Step 1: Identify Duplicates (30 seconds)
function findDuplicateParams(url) {
const params = new URL(url).searchParams;
const seen = new Set();
const duplicates = [];
for (const [key] of params.entries()) {
if (seen.has(key)) {
duplicates.push(key);
}
seen.add(key);
}
return duplicates;
}
// Usage
const url = 'site.com?utm_source=fb&utm_medium=cpc&utm_source=ig';
console.log(findDuplicateParams(url));
// Output: ['utm_source']Step 2: Remove Duplicates (30 seconds)
function removeDuplicateParams(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) {
// If keepFirst=false, update to last value
params.set(key, value);
}
}
urlObj.search = params.toString();
return urlObj.toString();
}
// Usage - keep first occurrence
const url = 'https://site.com?utm_source=facebook&utm_medium=cpc&utm_source=instagram';
console.log(removeDuplicateParams(url, true));
// Output: https://site.com?utm_source=facebook&utm_medium=cpc
// Or keep last occurrence
console.log(removeDuplicateParams(url, false));
// Output: https://site.com?utm_source=instagram&utm_medium=cpcStep 3: Determine Correct Value (2 minutes)
Decision tree:
If first value is correct:
✅ Keep: utm_source=facebook
❌ Remove: utm_source=instagram
If last value is correct:
❌ Remove: utm_source=facebook
✅ Keep: utm_source=instagram
If neither is correct:
❌ Remove both
✅ Add correct value
Prevention Strategies
Strategy 1: Check Before Adding
// ✅ CORRECT: Check if parameter exists before adding
function addUtmParam(url, key, value) {
const urlObj = new URL(url);
// Remove existing parameter if present
if (urlObj.searchParams.has(key)) {
urlObj.searchParams.delete(key);
}
// Add new value
urlObj.searchParams.append(key, value);
return urlObj.toString();
}
// Usage
let url = 'https://site.com?utm_source=google';
url = addUtmParam(url, 'utm_source', 'facebook');
// Result: https://site.com?utm_source=facebook (replaced, not duplicated)Strategy 2: Use URLSearchParams Set Method
// ✅ CORRECT: .set() replaces instead of duplicating
const url = new URL('https://site.com?utm_source=google');
url.searchParams.set('utm_source', 'facebook'); // Replaces google with facebook
url.searchParams.set('utm_medium', 'cpc'); // Adds new parameter
console.log(url.toString());
// https://site.com?utm_source=facebook&utm_medium=cpcStrategy 3: Validate in URL Builder
// Add to URL builder validation
function validateUtmUrl(url) {
const params = new URL(url).searchParams;
const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
const duplicates = utmParams.filter(param => {
return params.getAll(param).length > 1;
});
if (duplicates.length > 0) {
throw new Error(`Duplicate parameters detected: ${duplicates.join(', ')}`);
}
return true;
}Strategy 4: Server-Side Cleanup
// Express.js middleware to clean duplicate UTM parameters
function cleanUtmParams(req, res, next) {
const utmParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_content', 'utm_term'];
utmParams.forEach(param => {
if (Array.isArray(req.query[param])) {
// If duplicate, keep first value
req.query[param] = req.query[param][0];
}
});
next();
}
app.use(cleanUtmParams);Testing for Duplicates
Quick Visual Check
Look for parameter name appearing twice:
❌ DUPLICATE:
?utm_source=fb&utm_medium=cpc&utm_source=ig
↑ ↑
Same parameter name twice
✅ CORRECT:
?utm_source=fb&utm_medium=cpc&utm_campaign=spring
↑ ↑ ↑
Each parameter appears once
Automated Check
// Add to pre-launch validation
function auditUrl(url) {
const issues = [];
const params = new URL(url).searchParams;
const paramCounts = {};
// Count occurrences
for (const [key] of params.entries()) {
paramCounts[key] = (paramCounts[key] || 0) + 1;
}
// Report duplicates
Object.entries(paramCounts).forEach(([key, count]) => {
if (count > 1) {
issues.push({
parameter: key,
occurrences: count,
severity: 'critical'
});
}
});
return issues;
}✅ 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
If I have duplicate utm_source, which one does GA4 use?
Behavior is inconsistent across browsers and GA4 processing. Don't rely on it - fix the duplicate.
Can I use the same parameter name with different casing?
?utm_source=google&UTM_SOURCE=facebook
Parameter names are case-sensitive, so technically these are different. However, GA4 normalizes to lowercase, which can still cause issues. Avoid this pattern.
What if a platform automatically adds duplicate UTMs?
Contact platform support. If unavoidable, use server-side redirect to clean parameters before GA4 tracking.
How do I find all URLs with duplicate parameters?
Audit your campaign URLs with UTMGuard's duplicate parameter detection, or use the validation script above across all URLs.
Conclusion
Duplicate UTM parameters cause unpredictable GA4 tracking. Fix: Remove duplicates, keep only one value per parameter.
❌ DUPLICATE:
?utm_source=facebook&utm_source=instagram
✅ FIXED:
?utm_source=facebook
Each UTM parameter should appear exactly once per URL.
Technical Reference: Duplicate UTM Parameters Validation Rule