Custom UTM Parameters: What to Do When 5 Fields Run Out

Bhargav Dhameliya
Bhargav Dhameliya
September 9, 2026
5 min read
custom utm parameters beyond standard five featured

You need to know which of your 40 influencers drove that signup.

But utm_source is already instagram. utm_medium is social. utm_campaign is spring-launch. utm_content is carrying the creative variant. utm_term is doing nothing useful because this was never a paid search click.

You are out of fields. So you do the obvious thing and bolt one on: &ref=jane.

Here’s the thing. That link will work perfectly. The click will land. The conversion will fire. And jane will appear in exactly zero of your campaign reports.

I hit this the first time we ran a partner program at linkutm. I tagged 30 partner links, waited a week, opened GA4, and found nothing. The data was not lost. It was sitting somewhere I had not thought to look, in a form I had not set up to read.

A custom UTM parameter is any tracking key you add to a URL that is not one of the nine utm_ parameters GA4 recognizes. GA4 does not treat it as a campaign field. It rides along inside the page location and stays invisible until you extract it, send it as an event parameter, and register it as a custom dimension.

This post is not the setup walkthrough. We already published the full custom UTM parameter setup walkthrough with the GA4 steps, the use cases, and the examples. This one covers what that guide assumes you already accepted: what a custom parameter actually costs, and the three cheaper things to try before you spend anything.

Why Five Fields Run Out Faster Than You Think

Five fields run out when your business has a dimension that none of them describes.

Not when you have a lot of campaigns. That is a naming problem. Five fields handle 500 campaigns fine. They stop working when you need to slice by something that is genuinely a different axis: which partner, which store location, which pricing tier the visitor came from, which of nine agencies bought the placement.

Look at the difference:

  • Not a field shortage: “We have 200 campaigns and the report is messy.” You need a naming convention.
  • Real field shortage: “Every campaign runs through 40 partners, and partner is not source, medium, campaign, content, or term.” You need another axis.

The test I use: can you write the value into an existing field without destroying that field’s meaning? If utm_source=instagram-jane makes source stop meaning “the platform”, you have a real shortage.

Real talk, most requests I get for custom parameters fail that test. The team does not need a sixth field. They need everyone to stop spelling the campaign three different ways. That is the honest limitation of this entire topic: adding a field to a messy system makes the mess wider, not clearer.

Decision flow for custom UTM parameters showing the test question of whether a value fits an existing field, branching to fixing naming conventions or adding a new tracking axis

What Actually Happens When You Add ?ref= to a URL

GA4 reads a closed list. Anything outside that list is not a campaign field, full stop.

Google Analytics 4 recognizes nine utm_ keys. Three you should always use, six optional. If you want the mapping of which parameter becomes which GA4 dimension, that lives in our breakdown of all nine UTM parameters GA4 recognizes. I am not repeating it here.

The important part is what sits outside that list. Take this URL:

https://linkutm.com/pricing?utm_source=instagram&utm_medium=social&utm_campaign=spring-launch&ref=jane

GA4 parses the three utm_ keys into Session source, Session medium, and Session campaign. Then it stops. ref=jane is not ignored exactly, but it is not understood either. It gets swept up into page_location, which is the GA4 event parameter holding the full URL of the page, query string included.

So the value is in your property. It is just sitting inside a long string, unparsed, with no dimension attached to it.

And here is the trap that costs people a month. Open Reports, look at “Page path and screen class”, switch to the version with query string, and you will see it:

/pricing?utm_source=instagram&utm_medium=social&utm_campaign=spring-launch&ref=jane

There it is. Visible. Which feels like proof that tracking works. It is not. You cannot filter by partner, you cannot break a conversion count down by partner, and you cannot put partner in a report next to revenue. You can only read whole URLs one at a time, and every distinct combination of parameters creates its own separate row.

The honest limitation here: for a one-off campaign with five links, reading those rows manually is genuinely fine. Do not build a pipeline for five links.

Three Cheaper Options Before You Build a Custom Parameter

Try these in order. Each one costs less than a custom parameter, and two of them cost nothing.

Option 1: Use the GA4 parameters you are probably ignoring.

Most teams use five. GA4 accepts nine. utm_source_platform is a real, reported field, and it is empty in almost every account I have audited. If your missing axis is “which platform bought this”, that slot already exists and needs no setup at all.

The catch: two of the nine (utm_creative_format and utm_marketing_tactic) are collected but not reported in GA4 yet, per Google’s own documentation. Putting your partner name there means the data exists and no report shows it. Check what a parameter actually does before you adopt it.

Option 2: Encode structure into utm_content.

utm_content is a free text field. Nothing stops you from giving it internal structure with a delimiter:

utm_content=jane|reel|v2

One field, three facts: partner, format, variant. You split it later in Looker Studio or a spreadsheet. Zero GA4 configuration.

The catch is real though. Every unique combination becomes its own dimension value, so this multiplies your value count fast. 40 partners times 3 formats times 2 variants is 240 values in one field. That is how you end up in the (other) row and lose the long tail you built this for.

Option 3: Use utm_id as a join key.

If your extra data lives in a system you already own, do not push it through the URL at all. Put a short ID in utm_id, keep the partner, cost, and placement details in your own sheet or CRM, and join the two later.

This is the option people skip because it feels indirect. It scales better than either of the others. One field, one value, unlimited attributes attached to it outside GA4.

The catch: the join happens outside GA4, so nobody gets partner-level numbers by clicking around in the interface. Somebody has to own that report.

Comparison of three alternatives to custom UTM parameters: unused GA4 parameters, encoding structure into utm_content, and using utm_id as a join key with their trade-offs

The Four Costs Nobody Puts in the Tutorial

Every tutorial shows you how to create a custom dimension. Almost none of them tell you what you just spent. There are four costs, and two are permanent.

Cost 1: A dimension slot, out of a fixed quota.

Google caps custom dimensions per property:

Scope Standard property Analytics 360
Event-scoped 50 125
User-scoped 25 100
Item-scoped 10 25
Custom metrics 50 125

Dimension scope decides what the value attaches to: the single event, the whole user, or a product in a cart. Event scope is what a URL parameter almost always uses. Fifty sounds generous until three teams each register their own version of the same idea.

Cost 2: Cardinality.

Google is unusually direct about this one: “do not create unnecessary high-cardinality custom dimensions. High-cardinality dimensions may negatively impact your reports and explorations, and cause data to be condensed under the (other) row.”

Cardinality is just the count of unique values a dimension holds. A partner dimension with 40 values is fine. A dimension holding an order ID is not, and it will quietly damage the reports around it.

Cost 3: Registration is not retroactive. This one is permanent.

Here is the sequence that burns people, and it burned me:

  1. Monday: you launch, links carry ?ref=, the parameter starts arriving inside page_location.
  2. The following Monday: you notice no report shows it, so you register the custom dimension.
  3. From that moment, the dimension populates.
  4. Days 1 through 7 stay empty in your reports. Permanently.

The data was collected. The dimension did not exist to catch it, and GA4 does not go back and fill it in. So register the dimension before the campaign launches, not after you notice the gap.

There is one escape hatch. The GA4 BigQuery export stores raw page_location for every event, so if the export was already running you can parse those old URLs with SQL and recover the week. That only helps if you turned the export on before the campaign, which is its own version of the same lesson.

Cost 4: Silent truncation at 100 characters.

GA4 truncates event parameter values at 100 characters. Not an error, not a warning. It just cuts. page_location gets 1,000 characters, which is why the full URL survives while a long extracted value may not. Keep custom values short, and never stuff a full URL or a descriptive sentence into one.

Timeline showing the GA4 custom dimension retroactivity trap where data collected before the dimension was registered stays permanently empty in reports

The Capture Chain, and the Five Places It Breaks

A custom parameter has to survive five steps to reach a report. Understanding the chain matters more than memorizing the clicks, because when data goes missing, you are debugging a link in this chain.

  1. The URL carries the parameter. Breaks when a redirect or a platform strips it.
  2. page_location captures the query string. Breaks if someone configured the tag to send a cleaned URL with parameters removed.
  3. A tag extracts the value. Google Tag Manager reads the parameter out of the URL into a variable. Breaks on a typo in the parameter name, because matching is exact.
  4. The value ships as an event parameter. An event parameter is a named piece of data attached to a GA4 event. Breaks silently at 100 characters.
  5. The event parameter is registered as a custom dimension. Breaks if you skipped it, or registered it after launch.

Miss any one and you get the same symptom: an empty column. That is the frustrating part. Five different failures, one identical error message, which is no error message at all.

Step 2 deserves a warning, because it is the one people cause themselves. Stripping query parameters from page_location is a common and often sensible hygiene fix. It also destroys custom parameter capture, since that string was your only copy of the value. If someone on your team cleans URLs for reporting tidiness, your custom parameters go with them.

For the click-by-click configuration of steps 3 through 5, use the setup walkthrough in our guide. It covers the GA4 admin screens in order.

When a Custom Parameter Is the Wrong Answer

Sometimes the answer is no, and it is worth knowing the cases before you build.

Never put personal data in one. No email addresses, no customer IDs, no phone numbers. PII means personally identifiable information, and a URL is about the worst place to keep it. URLs get shared, pasted into chats, logged by servers, sent in referrer headers, and stored in analytics you do not control. Google’s terms prohibit sending PII to Analytics. A parameter like [email protected] is a compliance problem, not a tracking feature.

Redirects and shorteners are unreliable carriers. Some redirects preserve the full query string, some drop everything after the first parameter, and some platforms append their own click IDs that push you past length limits. Test the actual path your link takes, not a clean version of it in a browser tab. Click your own live link and read the final address bar.

One-off campaigns do not justify the pipeline. If the campaign runs for two weeks with six links, read the query strings manually and move on. The setup takes longer than the analysis would.

A messy naming convention will not be fixed by a new field. If partner names arrive as Jane, jane, and jane_smith, the custom dimension inherits all three as separate values. Custom parameters amplify whatever discipline you already have. They do not create any.

That last one is why we built enforcement into the custom UTM builder. It locks parameter names and value formats so a partner is spelled one way by everyone, before the link exists. A custom parameter is only worth its dimension slot if the values arriving in it are consistent.

Five-step capture chain from URL query string to GA4 report showing where custom parameter data breaks at each step including cleaned URLs and late dimension registration

Frequently Asked Questions

Can I invent my own utm_ parameter, like utm_partner?

No, and the prefix fools a lot of people. GA4 reads a fixed list of nine utm_ keys. Naming your parameter utm_partner does not make GA4 treat it as a campaign field, because the prefix is not what triggers recognition. The name being on Google’s list is. utm_partner behaves exactly like partner or ref, so it needs the same extraction and registration work as any other custom parameter.

Do custom parameters survive a short link or a redirect?

Usually, but never assume it. A properly configured redirect passes the full query string through to the destination. Some platforms strip parameters, some append their own click IDs, and some truncate long URLs. The only reliable check is to click your live short link and read the final URL in the address bar. Do that once per channel before the campaign ships, not after.

Can I get custom parameter data for dates before I set up the custom dimension?

Not in the standard reports. Custom dimension registration is not retroactive, so anything collected before you created the dimension stays empty in Explorations and reports. The exception is BigQuery. If the GA4 BigQuery export was already running, the raw page_location for those old events still contains your parameter, and you can parse it out with SQL. Without the export, that window is gone.

Is it safe to put a customer ID or email address in a custom parameter?

No. Sending personally identifiable information to Google Analytics violates Google’s terms of service, and URLs are exceptionally leaky. They appear in referrer headers, server logs, shared screenshots, and pasted messages. If you need to connect analytics data to a specific person, use a non-identifying ID that only your own systems can resolve back to a customer, and keep the mapping in your database.

Why does my custom dimension show (not set)?

(not set) means the event arrived without that parameter attached. Work backwards through the capture chain. Check the parameter name matches exactly, including case, between the URL and your tag configuration. Check the tag actually fires on the landing page. Check that nobody configured cleaned URLs that strip query parameters. And confirm the events you are looking at happened after the dimension was registered.

How many custom parameters is too many?

Practically, more than two or three per link and your team stops filling them in correctly. The technical ceiling is 50 event-scoped custom dimensions on a standard property, but you will hit the human limit long before the quota. Every extra field is another chance for a typo, another value to keep consistent, and another column to explain to whoever reads the report. Add one, prove it changes a decision, then consider the next.

Start With the Axis, Not the Field

Custom UTM parameters solve a genuine problem. They are just more expensive than the tutorials admit: a dimension slot from a fixed quota, a cardinality risk, a retroactivity trap that permanently costs you the data you collected before setup, and a five-step chain where any break produces the same empty column.

So before you add one:

  1. Confirm you have a real new axis, not a naming problem.
  2. Check whether an unused GA4 parameter already covers it.
  3. Try encoding the extra detail into utm_content, or a utm_id join key.
  4. If you still need it, register the custom dimension before the campaign launches.
  5. Keep values short, lowercase, and consistent.

Get the axis right and one custom parameter will answer a question you have been guessing at for months. Get it wrong and you have added a column of (not set) to a report nobody trusted anyway.

To build tagged links with custom parameters that stay consistent across your whole team, try the custom UTM builder at linkutm.

Bhargav Dhameliya

About Bhargav Dhameliya

Share this article

Ready to track your campaigns better?

Join thousands of marketers who use linkutm to build, track, and manage their marketing campaigns with ease.

Get Started for Free