If another website is firing your GA4 measurement ID, you prove it by opening the Hostname dimension in Google Analytics and looking for domains that are not yours. That single check is what separates this from referral spam, which is a different problem with a different remedy. Once it is confirmed, the setting that keeps the data out of your reports is a Web hostname traffic filter under Admin, and the setting that stops the tag firing on their page is a hostname condition in Google Tag Manager. Neither repairs the months already sitting in your property.
Table of Contents
Run the hostname check before you change a single setting
Open Explore in Google Analytics, start a blank exploration, add Hostname as a dimension and Sessions as a metric. Set the date range to cover whatever period looks wrong. You can also add Hostname to a standard report through the Add dimension control, which is quicker when you only want a glance.
What you should see is your own domain plus any subdomains you deliberately run. Anything else in that list arrived because a page on that host executed your tag.
The instinct at this point is to go straight to Admin and start blocking. You were expecting me to hand you the filter first. Do the check first and read it properly, because GA4 data filters are permanent by design and there is no undo for data you drop by mistake.
The hostname list tells you which of three problems you have
| What appears in Hostname | What is happening | What it needs |
|---|---|---|
| staging.yoursite.com, a preview URL, localhost or a bare IP address | Your own team copied the live tag into a non-production environment | A separate measurement ID per environment, plus a filter on the old host |
| A domain serving copies of your own pages | A scraper cloned the site and your tag came along with it | A takedown effort aimed at the host, plus a filter |
| A site with no relationship to yours at all | A developer reused a template, or somebody copied the ID deliberately | One email, then a filter |
The middle row deserves far more attention than its analytics side usually gets. A working copy of your site on another domain competes with you in search results, and it collects your customers’ form submissions under your branding with nobody you can hold responsible for either. Handle that through the hosting provider and the registrar rather than by writing to whoever built it, and keep dated screenshots and URLs as you go. The polluted analytics is the symptom that made you look. It is the smallest part of what you found.
The top row is more common than people expect and the least sinister of the three. A developer duplicating production into staging copies the tag with everything else. Fix that by giving each environment its own measurement ID rather than by asking people to remember to strip a script.
What it costs you while it runs
Session and user counts inflate, which is the part everyone notices. Then your conversion rate falls, because the number of conversions stays honest while the denominator grows underneath it. That is the expensive one. A campaign that converted perfectly well starts reading as a failure, and budget gets moved away from something that was working.
Geography and language distributions drift toward whoever the other site’s audience is. Landing page reports fill up with paths you do not have. If your GA4 property feeds conversions into Google Ads or into a reporting tool, every one of those inherits the same distortion without anyone flagging it.
Here is the part worth being blunt about. Google’s own documentation states that data filters are evaluated from the point of creation forward and do not affect historical data. Whatever period this ran for stays contaminated permanently. You cannot clean it, so the honest response is to write down the start and end dates somewhere and treat every comparison touching that window as unusable.
Referral spam is a different thing and the fixes do not overlap
People apply the wrong remedy here constantly, so it is worth being exact.
Referral spam arrives as hits carrying a fake referrer, designed to make you notice a domain and go and look at it. The spammer never loaded a page on your site and never ran your tag on theirs. A copied measurement ID is the opposite arrangement, where a real page on a real other domain executed your tag and the hostname it reports is that domain.
GA4’s List unwanted referrals setting was built for the first case and it does less than people assume even there. It recategorises the matching traffic as Direct. Those sessions stay in your reports and your totals do not move at all. If your complaint is inflated volume, that setting will not touch it.
The two controls that do work
Stop the tag firing on their page
If you deploy through Google Tag Manager, add a condition to the trigger on your GA4 configuration tag so it fires only when Page Hostname matches your own domains. Anyone who copies your container snippet or pastes your measurement ID onto another site then gets nothing, because the tag evaluates that condition in their visitor’s browser and declines. Where gtag.js is hardcoded into a template, the equivalent is a hostname check wrapped around the config call.
There is a limit to this and it matters. It only defends against copies that run your tag in a browser. Hits sent straight to Google’s collection endpoint never load your page and never see your condition. The authenticated server-side Measurement Protocol needs an api_secret that appears nowhere in your source, which raises the bar considerably, while the browser collection path needs no secret at all. That is exactly why a public measurement ID is enough for a pasted tag to work.
Stop the data being processed
Go to Admin, then Data collection and modification, then Data filters, and create a filter of type Web hostname traffic. Name the hostnames you want excluded. Leave it in Testing state first and check the results through the test filter name dimension in your reports, so you can see precisely what it would have removed before it removes anything.
Two properties of this filter shape how you use it. It excludes hostnames you name rather than allowing only the ones you approve, so the list needs maintaining as new hosts turn up. And once an exclude filter is active, Google’s wording is that the excluded data is never processed and will never be available in Analytics or in BigQuery. Get the hostname strings right before you switch it on.
Configure your domains is not the setting you are looking for
Under Admin, Data streams, your web stream, Configure tag settings, there is an option called Configure your domains. You were expecting me to tell you to list your domains there and be safe. It exists for cross-domain measurement, so a session carries across properties you own without breaking in the middle. It authorises nobody and it refuses nobody.
A short routine that keeps it from creeping back
- Look at the Hostname dimension once a month. It takes under a minute and it is the only early warning that exists.
- Annotate the dates any pollution started and stopped, somewhere your team will find them, so nobody builds a case on a broken comparison a year from now.
- Give staging and preview environments their own measurement IDs, so the honest half of this problem stops happening.
- Add each new rogue hostname to the filter as it appears, and confirm the filter is still Active after any property migration.
One closing point on escalation. If the other site is a real business with a real contact page, a single polite email naming the measurement ID and asking them to remove it works more often than you would guess, because most of the time it is genuinely accidental and the developer had no idea the ID was in the template they bought. If nothing comes back within a week, stop writing and let the filter do the work. Chasing someone who copied your tag on purpose is time you will never get back, and the filter has never needed their cooperation.