Google Ads has a dedicated error for this. Its wording:
The “Website redirects are losing click data” error appears when your redirects aren’t passing along your GCLIDs (Google Click Identifiers).
And its entire remedy:
You will need to identify what isn’t working properly on your server and have it fixed by your IT personnel so that the GCLID isn’t removed from the URL to allow the conversions to be tracked.
Identify what isn’t working. That is the whole instruction. Nothing about how to find which part of the chain drops it, which is the only question you actually have.
It takes one command.
The test
curl follows redirects and prints the headers of every hop. Send a request with a marker
parameter and read where it stops appearing.
curl -sIL "https://www.example.com/landing?gclid=TEST123&utm_source=probe" \
| grep -iE '^HTTP/|^location:'
Here is a real run against this site, which has two hops: www to the apex, then the
trailing slash normalisation.
HTTP/1.1 301 Moved Permanently
Location: https://301.sh/page-rules-where-every-setting-went?gclid=TEST123&utm_source=probe
HTTP/1.1 307 Temporary Redirect
Location: /page-rules-where-every-setting-went/?gclid=TEST123&utm_source=probe
HTTP/1.1 200 OK
Both hops carry the parameters through, and the final response is a 200. That is what healthy looks like, and it is worth running against a URL you know is fine before you trust the result on the one you suspect.
A broken chain looks the same except that one Location comes back bare:
HTTP/1.1 301 Moved Permanently
Location: https://example.com/landing/ <- gclid gone here
HTTP/1.1 200 OK
The hop whose Location first arrives without your marker is the one to fix. Everything after
it is innocent: once a parameter is gone it cannot come back.
Two details that change the answer:
Use -I, not a browser. A browser shows you the final URL and hides the chain that
produced it. It also runs the page’s own JavaScript, which can put a parameter back and make
a broken redirect look fine.
Watch the status codes as well as the Location. A 307 or 308 preserves the request
method; a 301 or 302 may not. If the click arrives on a POST, that difference is a second
way to lose data, separate from the query string.
On Cloudflare, check this first
Bulk Redirects have a parameter named preserve_query_string, and
its documented default is false.
A redirect built without touching it drops the whole query string, including the click ID.
That is the single most likely cause of the Google Ads error on a Cloudflare zone.
While you are in there, it is worth checking that the list is the size you think it is: the documented free plan allowance is 10,000 URLs, and a good number of accounts still have 20.
Now the part that surprises people. Read what enabling it actually does, verbatim:
the final redirect URL uses the original request’s query string. Any query string on the target URL is discarded
So the switch is not additive. It replaces. If your target URL carries its own parameters, turning on query string preservation deletes them.
That gives you two positions and no third:
preserve_query_string |
Incoming gclid | Parameters on your target URL |
|---|---|---|
false (default) |
dropped | kept |
true |
kept | discarded |
There is no setting that keeps both. A single Bulk Redirect cannot forward the click ID and append a parameter of your own at the same time. If you need both, the redirect has to be built somewhere that can compose the URL rather than choose between two halves of it.
What the test does not tell you
It finds the hop. It does not tell you why that hop behaves that way, and the cause is not always a redirect rule. Query strings also disappear in places that never appear in a curl trace: a link rewritten in an email client, an in app browser that strips parameters before the request is made, a client side router that replaces the URL after the page loads.
If the trace shows the parameter arriving intact at the 200 and your analytics still reports nothing, stop looking at the redirect. The loss is happening after the request, and that is a different investigation.
When one rule is not enough
For a single redirect on a single domain, this is a checkbox and a curl command.
It becomes something else when the click IDs matter across a set of domains: print codes,
partner links, campaign hostnames, each with its own rule, each with its own chance of being
the bare Location in someone’s trace. Checking them means running this test for every one,
by hand, whenever anything changes. That is the job 301.st exists to do.
For one rule, the checkbox is faster than any tool.