Send the visitor IP in a header Cloudflare won't rewrite - #49
Merged
Conversation
The tracking subrequest goes back out through Cloudflare's edge to reach the tunnel in front of Matomo, and the edge rewrites X-Forwarded-For to the connecting IP of that leg, so the visitor IP never survived the trip. Every visit was logged as the proxy in front of Matomo, which also meant no real geolocation and every visitor sharing one address. A custom header isn't managed by the edge and arrives intact.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
terminal | 481d894 | Commit Preview URL Branch Preview URL |
Aug 02 2026, 04:19 AM |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Every visit was landing in Matomo as the same private address (the proxy in front of it), so no visitor was distinguishable by IP and geolocation was a fallback guess.
proxy_client_headers[] = HTTP_X_FORWARDED_FORwas configured correctly on the Matomo side. The problem is upstream of that: the tracking subrequest leaves the Worker, crosses Cloudflare's edge again to reach the tunnel in front of Matomo, and the edge managesX-Forwarded-For— it rewrites the header to the connecting IP of its own leg, discarding what we set. By the time Matomo reads it, the visitor IP is gone./api/whoamiwas unaffected because it readsCF-Connecting-IPoff the inbound request inside the Worker, with no proxy chain in between — which is why the site could display an IP it apparently couldn't log.Switches to
X-Visitor-IP, which Cloudflare has no handling for and passes through untouched.Matomo side
The existing
X-Forwarded-Forandproxy_ipsentries can stay; they're just no longer load-bearing.