UTM Parameter Encoding Mistakes That Break Analytics

Updated

Most broken UTM data comes from characters that have a special meaning in URLs: &, #, ?, + and spaces, plus inconsistent capital letters. Use lowercase values with hyphens instead of spaces, percent-encode anything else once, and put the UTM parameters in the query string before any #. The examples below show what each mistake does to the parameters your analytics actually receives.

Google's help page for campaign URLs in Google Analytics 4 recommends always setting utm_source, utm_medium and utm_campaign, and notes that missing UTM parameters result in (not set) values in reports. Several encoding mistakes cause exactly that.

UTM encoding mistakes and what analytics receives A correct UTM link has the query before the fragment and lowercase hyphenated values. Below it, five broken examples: a raw ampersand splits the campaign, a raw hash drops later parameters, a second question mark hides utm_source, & renames utm_medium to amp;utm_medium, and double encoding leaves %20 in the report. UTM links: what the parser actually sees Correct /pricing?utm_source=newsletter&utm_medium=email&utm_campaign=spring-sale#plans Link contains Analytics receives utm_campaign=Q&A campaign "Q" + stray param "A" utm_campaign=launch #1&utm_source=x campaign "launch ", source lost ?id=5?utm_source=x id = "5?utm_source=x" &utm_medium=email "amp;utm_medium" → medium (not set) utm_campaign=spring%2520sale campaign "spring%20sale" utm_source=Newsletter / newsletter two different sources (case-sensitive) Rule: lowercase, hyphens, no & # ? + or spaces in values; query before #.
A UTM link split into parts, with the eight characters and habits that break it

The parameters GA4 reads

Parameter Purpose (from Google's help page)
utm_source Where the traffic comes from, such as a newsletter or site
utm_medium The marketing medium, such as email or cpc
utm_campaign The product, promotion or campaign name
utm_id Campaign ID that matches uploaded campaign data
utm_term Paid keyword
utm_content Distinguishes links or creatives with the same destination
utm_source_platform Platform that directs traffic to the property

Eight mistakes and what they do

Each "parsed as" column below was produced by the standard URL parser that browsers use (URL and URLSearchParams).

1. A raw & inside a value

?utm_campaign=Q&A-webinar&utm_source=linkedin

Parsed as: utm_campaign = Q, a stray parameter A-webinar, and utm_source = linkedin. The & ends the value. Encode it as %26 or, better, write qa-webinar.

2. A raw # inside a value

?utm_campaign=launch #1&utm_source=x

Parsed as: utm_campaign = launch and nothing else. Everything from # onward is the fragment, so utm_source is lost. RFC 3986 defines the query as ending at the first #. Encode # as %23 or avoid it.

3. A second ? instead of &

https://example.com/?id=5?utm_source=newsletter&utm_medium=email

Parsed as: id = 5?utm_source=newsletter and utm_medium = email. Only the first ? starts the query; later ones are ordinary characters. When a URL already has a query string, add UTM parameters with &.

4. UTM parameters after the

https://example.com/page#pricing?utm_source=newsletter

Parsed as: no query parameters at all; the hash is #pricing?utm_source=newsletter. The fragment is never sent to the server. Put the query first: /page?utm_source=newsletter#pricing.

5. & copied from HTML

?utm_source=newsletter&utm_medium=email&utm_campaign=spring-sale

Parsed as: utm_source = newsletter, then parameters named amp;utm_medium and amp;utm_campaign. Analytics no longer sees a medium or campaign, so they report as (not set). & is correct only inside HTML source, where the browser converts it back; see HTML entities vs URL encoding.

6. Encoding twice

?utm_campaign=spring%2520sale

Parsed as: utm_campaign = spring%20sale, with a literal %20 in your reports. This happens when a link builder, ad platform or redirect encodes a URL that was already encoded. See double URL encoding (%2520).

7. Mixed capitalization

utm_source=Newsletter, utm_source=newsletter and utm_source=NEWSLETTER are three different sources. Google's help page states that parameter values are case sensitive and recommends a strict naming convention with lowercase as standard practice.

8. Spaces and trailing spaces

A space must be sent as %20 or +. Which one you get depends on the tool that built the link, and a value pasted from a spreadsheet may carry an invisible trailing space that becomes %20 at the end. Form-style parsers read + as a space, but plain percent-decoders do not (see %20 vs + in URLs). Hyphens remove the question entirely.

Summary table

Mistake Example What analytics gets Fix
Raw & utm_campaign=Q&A Campaign Q qa or Q%26A
Raw # utm_campaign=launch #1 Campaign launch; later params lost launch-1 or %23
Second ? ?id=5?utm_source=x No utm_source Use &
UTMs after # #pricing?utm_source=x No UTMs Query before fragment
& &utm_medium=email (not set) medium Plain & outside HTML
Double encoding spring%2520sale spring%20sale Encode once
Mixed case Newsletter / newsletter Two sources Lowercase
Spaces spring sale %20, + or a split value spring-sale

Let the URL API handle the encoding and normalize values first:

const slug = v => v.trim().toLowerCase().replace(/\s+/g, "-");

function buildUtmUrl(base, params) {
  const u = new URL(base);                       // keeps existing query and #fragment
  for (const [k, v] of Object.entries(params)) {
    if (v) u.searchParams.set("utm_" + k, slug(v));
  }
  return u.toString();
}

buildUtmUrl("https://example.com/pricing#plans", {
  source: "Newsletter", medium: "Email", campaign: " Spring Sale 2026 ", content: "Q&A block"
});
// https://example.com/pricing?utm_source=newsletter&utm_medium=email
//   &utm_campaign=spring-sale-2026&utm_content=q%26a-block#plans

The function adds parameters with & when a query already exists, keeps the fragment at the end and encodes & and # inside values. Building links in a spreadsheet instead? The Google Sheets and Excel guide shows the ENCODEURL formulas.

A naming convention that avoids encoding

  1. Lowercase only.
  2. Letters, digits and hyphens only; no spaces, &, #, ?, + or /.
  3. A fixed list of utm_medium values (for example email, cpc, social).
  4. Dates in one format, such as 2026-11.
  5. One owner for the convention, and a shared sheet of approved values.

With values like spring-sale-2026, the encoded and decoded forms are identical, so nothing can be encoded twice or decoded wrongly.

Auditing campaigns that already ran

You cannot change data that has already been collected, but you can find the broken links and stop new damage:

  1. Look for odd values. In your acquisition reports, sort source, medium and campaign values alphabetically. Variants that differ only in case, values ending in a space or %20, and values containing %25 are encoding problems.
  2. Look for (not set). A sudden rise in (not set) medium or campaign for one source often means a template started producing & or a misplaced #.
  3. Trace the link. Find the email template, ad, social post or QR code that produced the URL and check its exact text.
  4. Fix at the source, then re-test by clicking the live link and checking the landing URL in the address bar.
  5. Document the convention so the next campaign uses the same values. Consistent future data is easier than cleaning old reports.

Paste the finished URL into the URL parser. It lists every parameter as analytics will read it, highlights utm_ parameters, and warns about uppercase values, spaces, & and double encoding. For one-off strings, the URL encode and decode operations on the universal encoder decoder show exactly what a value turns into.

Frequently asked questions

Are UTM parameters case-sensitive?

Yes, in Google Analytics 4. Google's help page says parameter values are case sensitive, so utm_source=google and utm_source=Google are reported as different sources. It recommends using lowercase as a standard practice.

Should I use spaces in utm_campaign?

Avoid them. A space has to be encoded as %20 or +, and links that are copied, shortened or rebuilt by other tools can end up with different encodings. Hyphens or underscores, such as spring-sale-2026, need no encoding at all.

Why does my report show (not set) for medium or campaign?

Google Analytics shows (not set) when a UTM parameter is missing. With encoding problems this usually means the parameter name was damaged, for example by & turning utm_medium into amp;utm_medium, or by a # or ? placed before it.

Split a URL into scheme, host, path, query and fragment, and decode every parameter.

Open the URL Parser

Sources