The short answer
Direct in GA4 doesn't mean somebody typed your URL in. It means GA4 had no idea where the session came from, so it used the fallback bucket. On B2B ad traffic that happens for four reasons, and you can usually find yours in an afternoon.
Work through them in that order. The first two account for most of the gap on LinkedIn traffic specifically, and the third is the one that quietly destroys your booking data.
The in-app browser strips your parameters
Someone taps your ad in the LinkedIn app. The page opens in LinkedIn's own embedded browser, not Safari or Chrome. Sometimes the referrer never gets set. Sometimes the link goes through an lnkd.in redirect that drops it. If your UTMs happen to be missing from that particular ad, there's nothing left for GA4 to read, and the session lands in Direct.
Then it gets worse. They don't fill anything in on their phone. They come back on a laptop three days later by searching your name, and that session gets credited to Organic Search. Same person, same buying decision, two sessions, neither one labelled LinkedIn.
- Audit every live ad's destination URL for a full UTM set. Source, medium, campaign, and content down to the individual creative.
- Keep the parameters consistent.
linkedinin one campaign andLinkedInin another will split into two rows in GA4. - Store the first UTM you ever see for that visitor rather than reading it live at form submit, so the laptop session three days later still carries it.
Consent mode and the cookie banner
If a visitor declines analytics cookies, GA4 either records nothing or records a modelled, cookieless ping with no source attached. Across UK traffic that's a noticeable slice. In Germany and the Nordics it can be enough to make a genuinely working campaign look like it sent nobody.
Two failure modes here and they look identical in the reports. One is legitimate refusal, which you have to live with. The other is a misconfigured banner blocking tags for people who did consent, or firing tags before consent is read so the session starts without a source. That second one is a bug and it's worth an hour of somebody's time.
"A rejected cookie banner does not stop the click. It only stops you seeing it."
- Check your consent platform is actually implementing Consent Mode v2 rather than just hiding tags, so you keep modelled data instead of a hole.
- Compare accepted against declined rates by country. If DACH sits far below the UK, treat those markets as directionally measured and lean on company-level influence there.
- Never treat a consent-heavy market as a dead channel on GA4 evidence alone. Check the CRM and the company engagement export before cutting spend.
Traffic in Campaign Manager, silence in GA4?
Book a 30 minute call and describe your setup. We will tell you which of the four causes it is likely to be.
Cross-domain: your booking tool restarts the session
This is the one that hurts, because it breaks precisely at the moment that matters. Visitor arrives from an ad, reads the page, clicks Book a call, and gets handed to Calendly or HubSpot Meetings on a different domain. Unless the two domains are linked, that's a brand new session. The booking is recorded as a referral from your own website, and the ad that paid for it disappears.
You end up with a report showing your highest-converting source is your own homepage. Every ad campaign shows a healthy click volume and no bookings.
- Add every third-party domain you hand visitors to into GA4's cross-domain configuration, and add them to the unwanted referrals list too.
- Append the stored attribution onto the booking link itself before the click, so the source travels with the visitor even if the session doesn't.
- Map the booking tool's own UTM fields across to your CRM, so the source lands on the deal record rather than dying in the scheduler.
- Fire a CTA click event before the redirect. Even if the destination loses everything, you still know which page and which campaign produced the intent.
The CRM only remembers one source
GA4 might have got it right and the CRM still says Direct. Most CRMs hold one original source and one latest source, both set by whatever touch happened to be visible at the time. A nine-month journey with eleven touchpoints gets squeezed into a single dropdown value, and the ad from February loses to the branded search in September every time.
We looked at a European SaaS client's new accounts for one month and found a good chunk of them had been served paid impressions beforehand. Not one was logged as LinkedIn. They were sitting under Direct, Organic Search and Offline Sources, all of which were technically true descriptions of the final step.
- Add hidden first-touch fields to every form so the CRM stores the original source separately from whatever it overwrites.
- Keep a self-reported "how did you hear about us" field. It is the only signal that survives all of the above.
- Run a monthly company-level match between ad exposure and new accounts, and log what the CRM called each one. That comparison is your evidence.
Diagnose it in twenty minutes
Do these in order and stop when you find the culprit. Usually you find two.
From the LinkedIn app, not desktop. Watch whether the UTMs survive into the address bar and whether GA4 realtime shows the source correctly.
Open every live ad and look at the destination. Missing or inconsistent UTMs are the single most common finding.
All the way through to the CRM record. Then read what source got written on it.
A gap under 20% is normal shrinkage. A gap over half means consent, ad blocking or a tag that is not firing.
A big Unassigned bucket points at tags firing before consent resolves, or events arriving without session context.
The fix, in order of payoff
- Full, consistent UTMs on every ad. Cheapest fix, biggest immediate difference.
- Cross-domain configuration plus unwanted referrals for your booking and form tools.
- First-touch capture in storage, written into hidden fields on submit.
- Attribution appended to outbound booking links before the redirect.
- Consent Mode v2 verified, with country-level accept rates on the dashboard.
- Self-reported source on the booking form, reviewed monthly against the tracked data.
Three of those six live entirely in GTM and your ad platform. Only the hidden fields and the booking link work usually need a developer, and even then it is an afternoon rather than a project.
What good looks like afterwards
Direct never goes to zero and shouldn't. People genuinely do type your URL in, and modelled cookieless sessions have to land somewhere. What changes is that your paid campaigns start showing sessions in roughly the proportion Campaign Manager led you to expect, bookings carry a source, and the argument about whether the ads send anyone stops being an argument.
Then you can go back to the harder question, which is how much pipeline the channel is genuinely influencing across a long cycle. That one needs a different method.
Read next
Common questions
If you would rather we just went in and fixed the tracking
- Full audit of ad destination URLs, GTM containers, consent configuration and cross-domain setup.
- UTM taxonomy applied consistently across every live campaign and creative.
- First-touch capture written into hidden fields and passed through to the CRM.
- Booking and form handoffs fixed so the source survives the redirect.
- A before and after read on how much traffic was being misfiled, with the numbers to show it.
Starter £975/mo, Growth £1,725/mo, Scale £4,025+/mo. Tracking rebuilds usually take two to three weeks and sit inside the monthly retainer rather than as a separate project fee.

