Server-side tagging is often sold as the privacy-friendly option: the browser talks to your own server, and your server decides what goes out to Google Ads, Floodlight, Meta and the rest. That is only true if your server actually decides something. The request that reaches a server-side Google Tag Manager (sGTM) container comes from the visitor’s connection, so the server knows their IP address, and the tags you fire downstream can forward it.

Google has now published a short help page describing how to mask that IP inside the server container, before any tag sees it. This guide explains what those steps actually do, what they bring, the five places where the IP can still leave, how to set it up tag by tag, how to verify it in Preview, and what to measure afterwards. Where I am drawing a conclusion from the mechanism rather than from Google’s wording, I say so explicitly.

Contents

  1. The short version
  2. Why the IP is in your server container at all
  3. What Google’s method does
  4. Transformations in one table
  5. What it brings
  6. What it does not do
  7. Where it breaks: five leaks
  8. Which tags need what: a decision tree
  9. How to set it up, step by step
  10. How to verify it in Preview
  11. What to expect afterwards
  12. FAQ
  13. Checklist
  14. Glossary
  15. Sources

The short version

Why the IP is in your server container at all

When a browser sends a hit to your sGTM endpoint, the HTTP request comes from the visitor’s connection. The server knows where it came from, the same way any web server does. A client in your container (typically the GA4 client) turns that request into an event: a set of fields that tags read.

One of those fields is ip_override. Google’s list of common event data describes it as “the IP address of the user in IPv4 or IPv6 format”. Tags built on Google’s templates read that field and pass it on to their own endpoints.

A useful way to picture it: the event is a parcel, and every tag is a courier. Whatever is in the parcel when the couriers pick it up is what gets delivered. Redaction means changing the content of the parcel before the couriers arrive.

Where IP redaction happens in a server-side GTM container The browser request reaches the sGTM client, which builds event data containing ip_override with the full IP. An Augment event transformation replaces it with a truncated IP before tags read it. Google Ads and Floodlight then send the truncated IP. GA4 already applies partial redaction. A vendor tag reading its own field or the request is not covered. Browser 198.51.100.42 Server-side GTM container Client builds the event Event data ip_override = .42 Transformation Augment event What tags read ip_override = .0 Tags fire after transformations Google Ads receives 198.51.100.0 Floodlight receives 198.51.100.0 GA4 partial redaction by default Vendor reading its own field not covered: full IP
Figure 1. The transformation edits the event before tags read it. A tag that takes the IP from somewhere else is not covered.

What Google’s method does

The method has two pieces.

1. A variable that truncates the IP

You create a custom template variable with two lines of sandboxed JavaScript:

const getAnonymizedIpAddress = require('getAnonymizedIpAddress');
return getAnonymizedIpAddress();

The sGTM API reference describes exactly what that function returns:

Input Rule Example Addresses sharing the result
IPv4 Last octet set to 0 198.51.100.42 → 198.51.100.0 256 (a /24 block)
IPv6 Last 80 bits set to 0, first 48 kept 2001:db8:cafe:1234:5678:90ab:cdef:1234 → 2001:db8:cafe:: 280 (a /48 block)
Invalid or unresolved Returns :: “always safe to use as ip_override” —

The last column is plain arithmetic, not a Google statement. The template needs the user_ip permission. In everyday words: you keep the street name and erase the house number.

2. A transformation that swaps the field

Google’s method uses an Augment event transformation that sets ip_override to the truncated value. The help page is explicit about timing: the redaction happens “before any individual tag accesses the data”. You then restrict the transformation to the tags that should receive the truncated IP, through Matching Conditions or Affected Tags.

Transformations in one table

Transformations are rules that sit between the client and the tags. There are three types:

Type What it does Risk Google documents Use for the IP
Allow parameters Only the listed parameters reach the tags. “Event parameters that aren’t explicitly defined are discarded.” Removes everything not listed, “even values required by Google tags”. No
Augment event Changes the value of existing parameters or adds new ones. “Tags might not work as expected when the parameters they use are modified.” Yes: Google’s method
Exclude parameters Removes specific parameters before tags read them. Can stop a tag from working if the parameter is required. Possible, but you remove the IP instead of truncating it: test the tag first

Default evaluation order is Allow, then Augment, then Exclude. You can change it with a priority value. By default a transformation applies to every tag and has no matching condition.

What it brings

What it does not do

Where it breaks: five leaks

Leak 1 — vendors that don’t read ip_override

Google says it plainly in the same help page: not all third-party vendors use the ip_override field. Some read the IP from a custom header or from a parameter of their own. For those tags, your transformation changes a field they never look at. The full IP still goes out. Google’s answer is one more Augment event transformation on that vendor’s exact field.

Leak 2 — templates that read the request itself

The sGTM API also exposes getRemoteAddress(), which reads the originating IP from the request: the Forwarded and X-Forwarded-For headers, or the remote address. Hypothesis, not Google’s wording: a transformation edits event data, so a tag template that calls getRemoteAddress() directly would not be affected by it. Check the template’s permissions: a template that asks for read_request access to those headers deserves a closer look.

Leak 3 — weaker matching

Some vendors use the IP to recognise the person behind a conversion. Meta’s Conversions API documentation says that sending both client_ip_address and client_user_agent “may help improve event matching”, and prefers IPv6 when available. A truncated IP carries less signal. Fewer matched events can mean fewer attributed conversions, and less data for automated bidding. This is not a leak of data; it is a leak of performance, and it should be measured.

Leak 4 — a scope that is too wide

Google’s Transformations documentation states that “by default, the transformation applies to all tags”, and warns that tags might not work as expected when the parameters they use are modified. Leaving the scope at “all” by reflex is how a privacy fix turns into a measurement incident.

Leak 5 — infrastructure logs

The container is not the only place the request is recorded. On Cloud Run, Google’s setup guide says that by default “information about every single request” is logged, and recommends disabling request logging to control costs. Cloud Logging’s request record includes a remoteIp field: “the IP address (IPv4 or IPv6) of the client that issued the HTTP request”. A transformation does nothing to those logs. Decide on request logging and retention at the infrastructure level, with the same care.

Which tags need what: a decision tree

Decision tree: how to cover each tag For each tag: if it is a GA4 server tag, partial redaction is already applied. Otherwise, if it reads ip_override, add it to the main transformation scope. If it reads another event field, add a dedicated Augment event transformation on that field. If it reads the request with getRemoteAddress, review or replace the template. For each server tag GA4 server tag? yes Already partial no action needed no Where does it read the IP? ip_override another event field the request itself Add to the main transformation scope Google Ads, Floodlight, many vendors Dedicated Augment event on that exact field scoped to that tag only Review the template (getRemoteAddress) transformation likely ineffective
Figure 2. One question per tag: where does it read the IP? The answer decides the fix.

How to set it up, step by step

  1. Take inventory. List every tag in the server container. For each one, write down where it reads the IP: vendor documentation, the template code and its permissions, or the request as seen in Tag Assistant. This is the step most teams skip, and it is the one that prevents gaps.
  2. Create the variable. Variables → New → custom template variable with the two lines above. Grant the user_ip permission.
  3. Create the transformation. Transformations → New → Augment event. Field: ip_override. Value: the variable.
  4. Scope it. Affected tags: Google Ads, Floodlight, and third-party tags that read ip_override. Not “all tags” by default.
  5. Handle the outliers. For each tag that reads the IP from another field, add one more Augment event transformation on that exact field, mapped to the same variable, scoped to that tag only. For templates that read the request, see leak 2.
  6. Verify, then publish. Preview, trigger your tags, open each outgoing request, read the IP. Then save and publish the container, and note the go-live date somewhere your reporting team will find it.
  7. Close the infrastructure side. Decide on Cloud Run request logging and log retention (leak 5).

How to verify it in Preview

sGTM Preview has five tabs: Request, Tags, Variables, Event Data and Console. Two of them matter here.

What you read Verdict
IPv4 ending in .0 Redacted
IPv6 ending in :: after the first three groups Redacted
:: alone IP unresolved, nothing sent
Full address Not covered: go back to the decision tree for that tag

Tags out of scope should behave exactly as before. If a tag stopped firing, check the Console tab: the transformation probably modified a field it depends on.

What to expect afterwards

Two checks, on two time frames.

Same day: compliance

After two full weeks: performance

A way to read it: for every 100 conversions before, 97 after at the same budget is a small gap, and you keep the setting. A sharp drop on one platform only points to that tag, not to the whole setup. Look at what that vendor uses the IP for, and decide on that tag alone, with the reason written down.

The expected outcome is modest and concrete: one less personal-data leak, proof you can show, and a cost that is measured rather than assumed.

FAQ

Do I need this for GA4?

No. Google states that Google Analytics server tags already apply partial IP redaction by default.

Does it work for Meta, TikTok or other third-party tags?

Only for templates that read ip_override. Google says many major third-party templates do, and not all. Check each one in Tag Assistant or in the template code.

Is a truncated IP still personal data?

It can be. Truncation reduces precision; it does not by itself take the data out of GDPR scope. Ask your DPO.

Will it lower my ad performance?

It can, for vendors that use the IP for matching. Measure it on two full weeks before and after, per platform.

Can I remove the IP entirely instead?

An Exclude parameters transformation can remove ip_override. Google warns that removing a parameter a tag needs can stop it from working. Test each tag in Preview.

Does it clean my server logs?

No. Cloud Run request logs record the client IP independently of the container. Manage them at the infrastructure level.

Checklist

Glossary

Related reading

Sources


Not sure your own tracking is right?

Book a call Or start with the free analytics audit →