Double Question Mark URL Error: Why GA4 Sees Corrupted Data
Two ?? in your URL breaks parameter parsing. GA4 gets corrupted campaign data. Here's why it happens and the instant fix.
You checked your campaign URL. You saw TWO question marks:
shop.com?page=products?utm_source=facebook&utm_medium=cpc
↑ ↑
First ? Second ? (ERROR!)
GA4 shows corrupted campaign data. Some parameters tracked, others missing. Your attribution is a mess.
Two question marks breaks URL parameter parsing. Here's why and how to fix it.
Table of contents
- The Problem: Only One ? Allowed Per URL
- Why This Happens
- How Browsers Parse URLs (Correctly)
- With Double Question Marks (Broken)
- How This Mistake Happens
- Scenario 1: Concatenating URLs with Existing Parameters
- Scenario 2: URL Builder Logic Error
- Scenario 3: Copy-Paste Mistakes
- The Fix
- Step 1: Find Double Question Marks
- Step 2: Replace Second ? with &
- Step 3: Use Smart Concatenation
- Real Example: Email Platform Concatenation Error
- Prevention: URL Validation
- Bulk Fix for Campaign URLs
- FAQ
- Can I have multiple question marks in a URL?
- What if my parameter value contains a question mark?
- How do browsers handle multiple question marks?
- Will this break my links?
- How do I prevent this in URL builders?
- Can URL shorteners fix this?
- What if the second ? is in a redirect parameter?
- Does this affect all query parameters?
- How do I test if URLs are broken?
- Can this happen in shortened URLs?
- Related Resources
- Internal Guides
- External Resources
- 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: Only One ? Allowed Per URL
URLs can have only ONE question mark starting the query string:
✅ CORRECT:
shop.com?param1=value1¶m2=value2¶m3=value3
↑ ↑ ↑
First ? & separator & separator
❌ WRONG:
shop.com?param1=value1?param2=value2¶m3=value3
↑ ↑
First ? Second ? (breaks parsing)
What breaks:
- Parameter parsing fails
- GA4 receives corrupted data
- Campaign attribution incomplete or missing
- Some params captured, others lost
Why This Happens
How Browsers Parse URLs (Correctly)
URL: shop.com?page=products&utm_source=facebook
↑
Question mark starts query string
Query string: page=products&utm_source=facebook
Parameters parsed:
- page = products
- utm_source = facebook
With Double Question Marks (Broken)
URL: shop.com?page=products?utm_source=facebook
↑ ↑
First ? Treated as part of value!
Query string: page=products?utm_source=facebook
Parameters parsed:
- page = products?utm_source=facebook (WRONG!)
- utm_source = MISSING (not parsed)
The browser treats the second ? as part of the first parameter's value, not as a separator.
😰 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
How This Mistake Happens
Scenario 1: Concatenating URLs with Existing Parameters
// Base URL already has parameters
const baseUrl = 'shop.com?page=products';
// ❌ WRONG - Adds another ?
const campaignUrl = baseUrl + '?utm_source=facebook';
// Result: shop.com?page=products?utm_source=facebook
// ✅ CORRECT - Check for existing ?
const separator = baseUrl.includes('?') ? '&' : '?';
const campaignUrl = baseUrl + separator + 'utm_source=facebook';
// Result: shop.com?page=products&utm_source=facebookScenario 2: URL Builder Logic Error
function buildCampaignUrl(base, utms) {
// ❌ WRONG - Doesn't check if base has parameters
return base + '?' + utms;
}
// Input: buildCampaignUrl('site.com?sort=price', 'utm_source=email')
// Output: site.com?sort=price?utm_source=email (BROKEN!)
// ✅ CORRECT - Smart concatenation
function buildCampaignUrl(base, utms) {
const separator = base.includes('?') ? '&' : '?';
return base + separator + utms;
}
// Input: buildCampaignUrl('site.com?sort=price', 'utm_source=email')
// Output: site.com?sort=price&utm_source=email (WORKS!)Scenario 3: Copy-Paste Mistakes
You have: site.com?category=shoes
You want to add: ?utm_source=facebook&utm_medium=cpc
❌ Result: site.com?category=shoes?utm_source=facebook&utm_medium=cpc
↑
Double question mark
✅ Should be: site.com?category=shoes&utm_source=facebook&utm_medium=cpc
↑
Ampersand, not ?
The Fix
Step 1: Find Double Question Marks
Search your campaign URLs for patterns:
- Literal
?? - Regex:
\?.*\?
Step 2: Replace Second ? with &
❌ BEFORE:
shop.com?page=products?utm_source=facebook&utm_medium=cpc
✅ AFTER:
shop.com?page=products&utm_source=facebook&utm_medium=cpc
↑
Changed ? to &
Step 3: Use Smart Concatenation
JavaScript helper function:
function smartConcat(baseUrl, params) {
// Check if baseUrl already has parameters
const separator = baseUrl.includes('?') ? '&' : '?';
return baseUrl + separator + params;
}
// Usage examples
smartConcat('site.com', 'utm_source=facebook');
// Output: site.com?utm_source=facebook
smartConcat('site.com?page=1', 'utm_source=facebook');
// Output: site.com?page=1&utm_source=facebook
smartConcat('site.com?page=1&sort=asc', 'utm_source=facebook');
// Output: site.com?page=1&sort=asc&utm_source=facebookPython helper:
def smart_concat(base_url, params):
separator = '&' if '?' in base_url else '?'
return f"{base_url}{separator}{params}"
# Usage
smart_concat('site.com', 'utm_source=facebook')
# Output: 'site.com?utm_source=facebook'
smart_concat('site.com?page=1', 'utm_source=facebook')
# Output: 'site.com?page=1&utm_source=facebook'Real Example: Email Platform Concatenation Error
Platform: Mailchimp campaign Problem: Email template with merge tag logic error
Template code:
<a href="{{website}}?{{utm_parameters}}">Click here</a>Variables:
website = https://shop.com?category=products
utm_parameters = utm_source=mailchimp&utm_medium=email
Result (BROKEN):
https://shop.com?category=products?utm_source=mailchimp&utm_medium=email
↑
Double question mark
GA4 received:
Parameter "category" value: products?utm_source=mailchimp&utm_medium=email
utm_source: (missing)
utm_medium: (missing)
Fix the template:
<a href="{{website}}&{{utm_parameters}}">Click here</a>Or use conditional logic:
<a href="{{website}}{{#if website contains '?'}}&{{else}}?{{/if}}{{utm_parameters}}">Click here</a>Result (FIXED):
https://shop.com?category=products&utm_source=mailchimp&utm_medium=email
Prevention: URL Validation
Before launching campaigns:
function validateUrl(url) {
const questionMarks = (url.match(/\?/g) || []).length;
if (questionMarks === 0) {
return { valid: true, issue: 'No parameters' };
}
if (questionMarks === 1) {
return { valid: true, issue: null };
}
return {
valid: false,
issue: `Found ${questionMarks} question marks (only 1 allowed)`
};
}
// Usage
validateUrl('site.com?utm_source=x');
// { valid: true, issue: null }
validateUrl('site.com?page=1?utm_source=x');
// { valid: false, issue: 'Found 2 question marks (only 1 allowed)' }Bulk Fix for Campaign URLs
Google Sheets formula:
=SUBSTITUTE(A2, "?utm", "&utm")
This replaces ?utm with &utm across all URLs. Works when UTM parameters are the second set of parameters.
Excel formula:
=SUBSTITUTE(A2,"?utm","&utm")
CSV batch processing (Node.js):
const fs = require('fs');
const csv = require('csv-parser');
const results = [];
fs.createReadStream('campaigns.csv')
.pipe(csv())
.on('data', (row) => {
// Fix double question marks
row.url = row.url.replace(/(\?.+)\?/, '$1&');
results.push(row);
})
.on('end', () => {
console.log('Fixed URLs:', results);
});✅ 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
Can I have multiple question marks in a URL?
No. RFC 3986 (URL standard) defines only ONE question mark to start the query string. Additional parameters must use &.
What if my parameter value contains a question mark?
URL-encode it: ?message=hello%3Fworld where %3F is the encoded ?. This way the ? is part of the value, not a separator.
How do browsers handle multiple question marks?
They treat the second ? as part of the first parameter's value, not as a parameter separator. This breaks parsing.
Will this break my links?
Yes. Multiple question marks break parameter parsing, causing:
- Tracking failures in GA4
- Broken page functionality (if page relies on parameters)
- Corrupted data in all analytics platforms
How do I prevent this in URL builders?
Add logic to check if the base URL already contains ? before adding new parameters:
const separator = url.includes('?') ? '&' : '?';
const newUrl = url + separator + newParams;Can URL shorteners fix this?
No. URL shorteners will shorten the broken URL but won't fix the parsing issue. Fix the URL first, then shorten it.
What if the second ? is in a redirect parameter?
If you're passing a redirect URL as a parameter, URL-encode the entire redirect:
✅ Correct:
site.com?redirect=https%3A%2F%2Fother.com%2Fpage%3Fid%3D1&utm_source=email
❌ Wrong:
site.com?redirect=https://other.com/page?id=1&utm_source=email
Does this affect all query parameters?
Yes. Any parameters after the second ? won't parse correctly:
- UTM tracking
- Custom page parameters
- Affiliate codes
- Session IDs
- Any query string data
How do I test if URLs are broken?
- Copy the URL
- Paste into browser
- Check Network tab in Dev Tools
- Verify which parameters the server received
- Compare to what you expected
Can this happen in shortened URLs?
Yes, if the original URL has double question marks before shortening. Always validate URLs before shortening.
Related Resources
Internal Guides
- Fix Multiple Question Marks - Detailed solution
- Fix Missing Query Separator - Missing
?fix - Prevent URL Syntax Errors - Best practices
- UTM Parameters Not Working - General troubleshooting
External Resources
- RFC 3986 - URL Syntax - Official URL standard
Conclusion
Double question marks break URL parameter parsing. Only ONE ? is allowed per URL.
Quick fix:
- Find URLs with multiple
? - Replace second (and any additional)
?with& - Test in GA4 Real-time
❌ WRONG: site.com?a=1?b=2?c=3
✅ RIGHT: site.com?a=1&b=2&c=3
Prevention:
const separator = url.includes('?') ? '&' : '?';
const fixedUrl = url + separator + newParams;30 seconds to fix. Complete tracking restored.
Technical Reference: Multiple Question Marks 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