TRACKING SPECIALIST — BARIS ASA · LONDON
Synctag
Start the check → TRACKING SPECIALIST — BARIS ASA · LONDON

READING ROOM › SYMPTOM FILES › SYM-008

SYMPTOM FILE SYM-008 FILED 03 NOV 2026 · REVISED 03 NOV 2026

Implementing Consent Mode v2 correctly with server-side GTM: what to set, what to gate, how to prove it.

ALSO FILED AS
  • “consent mode v2 server-side GTM”
  • “how to check consent mode is working in sGTM”
  • “consent mode not working server-side GTM”
  • “Facebook Conversions API consent server-side GTM”
  • “Meta tag firing without consent server-side”
  • “how to block Meta CAPI when consent is denied in sGTM”
  • “TikTok Events API consent server-side GTM”
  • “ad_storage denied server container”
  • “gcs parameter server-side GTM”
  • “x-ga-gcs trigger”
  • “Meta CAPI firing without consent server-side GTM”
  • “consent mode v2 implementation checklist GTM”

Baris Asa, tracking consultant, London · Last checked: November 2026

Google’s guide sets out the correct Consent Mode v2 setup: load the banner before any tag, default every consent type to denied for visitors who must opt in, and update them when the visitor answers. Google’s tags then read that state on their own, in the browser and in a server container.

In server-side GTM, also gate every non-Google tag: add a condition that lets Meta, TikTok or Pinterest fire only on a yes. Without it, Meta counts people who declined. With too strict a gate, it misses people who agreed. Then prove it with two Preview sessions (GTM’s test mode), one declined and one accepted.

Done right, Google Ads still estimates the sales from visitors who declined, once the account passes Google’s threshold of 700 ad clicks over 7 days per country and domain grouping (F-201 ).

A rough first look. Take one week. Compare Purchase events in Meta Events Manager (not attributed conversions) with shop orders, and set that against your banner tool’s consent rate (Cookiebot, OneTrust and CookieYes all report one). If Meta shows clearly more purchases than consenting buyers, suspect a missing gate or duplicate Pixel and server events (F-102 ). If it shows clearly fewer, suspect too strict a gate or ad blocker and Safari loss (F-401 ). It points you at the test; it is not the diagnosis.

If you don’t run GTM yourself, ask whoever does for one screenshot: the Tags tab from a server container Preview session where they declined everything. Any Meta, TikTok or Pinterest tag under Tags Fired is the fault.

Everything below is for whoever manages the containers.

In the web container (Google: set up consent mode, Tag Manager consent settings):

  1. Load the banner on the Consent Initialization trigger, through a consent mode template. Google says it makes sure consent settings take effect before any other trigger fires.
  2. Set defaults to denied for visitors who must opt in (EEA, UK and Switzerland at least), with a region-specific default if you trade wider. All four v2 types: ad_storage, analytics_storage, ad_user_data, ad_personalization.
  3. Add wait_for_update if the banner loads asynchronously, so Google’s tags wait a set number of milliseconds for the answer.
  4. Turn on consent overview (Container Settings, Additional Settings). Google’s tags have built-in consent checks. Non-Google web tags need Additional Consent Checks, which fire the tag only when every listed type is granted.
  5. Choose basic or advanced on purpose. Basic keeps Google tags from loading until the visitor answers. Advanced loads them straight away and, while consent is denied, sends cookieless pings: measurements with no cookies stored on the device. Basic means Google models declined visitors with a general model; advanced lets it use an advertiser-specific one (Google: basic and advanced).

In the server container (the GTM setup on your own subdomain that forwards events to Google and Meta; Google: consent mode with server-side Tag Manager):

  1. Nothing to configure for Consent Mode itself. A GA4 client claims the requests and passes the consent state to Google’s server tags.
  2. The Conversion Linker tag is in the container, for Google Ads conversions and Floodlight.
  3. Every non-Google tag is gated on the visitor’s answer.
  4. Two Preview sessions prove it, one declined and one accepted.
  • Meta shows fewer conversions than it should. If the Meta tag fires only when advertising and analytics consent are both granted, a visitor who accepted advertising but declined analytics never reaches Meta. If your banner puts Meta under advertising consent, gate on advertising consent alone (the trigger is below).
  • Meta gets events from visitors who declined. If the Meta tag fires on every GA4 event, in advanced mode that includes the cookieless pings from visitors who said no. Same fix: the gate.
  • The first page view can carry denied. In advanced mode, a visitor who accepts after the page loaded may have sent that page view before the answer. Later events, usually including the purchase, carry granted. Small remarketing gaps can come from this.
  • Ad-blocker or Safari loss mistaken for a consent fault. Consent decides whether a tag may fire. Ad blockers can stop the request reaching your server at all, and Safari shortens how long cookies and click IDs last. Neither is a consent setting. Both are filed under F-401 .

Check the browser first. If the default isn’t set before tags fire, or the update never runs, the server can only pass on a wrong answer. Google’s consent debugging guide covers that side in Tag Assistant. Then open server container Preview (Google: Preview and debug) and run two sessions.

Session one: decline everything.

  1. Open the first GA4 request. On the Request tab, check the GA4 client claimed it, then open Incoming HTTP Request and find gcs. In advanced mode it should show advertising consent denied. In basic mode no GA4 request should arrive at all.
  2. Look at the response headers. Google says no Analytics cookies are set or read while consent is denied, so there should be no Set-Cookie for an Analytics cookie (such as FPID).
  3. On the Tags tab, Meta, TikTok and any other non-Google tags should sit under Tags Not Fired. If one fired, it is forwarding declined visitors.

Session two: accept everything.

  1. gcs should now show both granted. The Meta tag should be under Tags Fired. Open its request in Outgoing HTTP Requests and check the status code Meta sent back.
  2. Place a test conversion. The Google Ads conversion tag should fire, with the Conversion Linker tag in the container.
  3. If you set defaults by region and serve your scripts through the tagging server, check the Region value (the steps are further down).

Then check Meta’s side. Put the Test Events code from the Test Events tab in Events Manager (select your dataset or Pixel) on the Meta server tag and repeat both sessions. Declined: nothing arrives. Accepted: the event appears as a server event (Meta: Conversions API). Take the code off afterwards.

They read the consent state and adjust. Google gives this behaviour when consent is denied:

Server tagWhen consent is deniedNeeds
GA4Basic: nothing sent, no cookies. Advanced: cookieless pings, no Analytics cookiesGA4 client
Google Ads conversion trackingNo Ads cookies written or readConversion Linker tag
Google Ads remarketingRequest and cookies blocked
Floodlight (Campaign Manager’s conversion tag)Request and cookies blockedConversion Linker tag

Modelling of declined visitors’ conversions has a threshold: consent mode correctly implemented and 700 ad clicks over 7 days per country and domain grouping (Google Ads Help). Gate only the non-Google tags. Blocking the GA4 or Google Ads tags in the server on denied consent throws away the pings that modelling runs on.

Google’s guide covers Google’s tags and stops there. A Meta Conversions API tag in the server container fires whenever its trigger matches, whatever the visitor chose.

The consent state rides on the GA4 request. Google documents gcs (storage consent: ad_storage and analytics_storage) and gcd (the detailed choice), and says both may change (consent mode overview). It doesn’t publish the encoding. It doesn’t list x-ga-gcs, the event data key the GA4 client exposes gcs under, either (common event data). What follows is the working reading, not a spec.

That reading is G1, then one digit for advertising, then one for analytics. Stape’s examples give G100 (no consent) and G111 (consent), and its Meta template fires on G110; G101 is inferred from the pattern:

x-ga-gcsAdvertisingAnalytics
G100denieddenied
G101deniedgranted
G110granteddenied
G111grantedgranted

Confirm it with the two sessions above, and re-check after Google tag updates. Then pick one gate per tag:

  1. A trigger condition. Create an Event Data variable with key path x-ga-gcs. If your banner puts Meta under advertising consent, fire the Meta tag only when the variable matches RegEx ^G11: advertising granted, whatever the analytics choice. equals G111 is the strict version: it drops visitors who accepted advertising but declined analytics.
  2. The template’s own consent setting (Stape’s, for example). Stape says its Meta, TikTok, Snapchat and Pinterest server tags support consent mode, with a “Send data if marketing consent is given” checkbox that fires on G110 or G111, or on the ad_storage status its Data Tag sends. Confirm it in Preview like any other gate (Stape’s guide).

Three limits:

  • gcs carries storage consent only. Per Google, the detailed choice, including ad_user_data (sending user data to Google for advertising), is in gcd. If your banner asks about the two separately, gate on a source that carries both, such as the banner’s own consent event sent to the server.
  • x-ga-gcs only exists on GA4 requests. A tag triggered from another client finds it empty and never fires.
  • Meta’s Limited Data Use flag is not a consent gate. Meta’s data_processing_options field covers US state privacy laws only (Meta for Developers), not UK or EU consent.

Gating decides whether Meta gets the event. Counting it once is a separate check: Pixel and server events need the same event_id, filed under F-102 . Which server route to send Meta’s events through is compared in Meta Conversions API setup options, and whether you need a server container at all in Server-side vs client-side GTM.

Do region-specific defaults need anything in the server container?

Only if you set region-specific defaults and serve gtm.js or gtag.js through your tagging server. Google’s guide frames this for advanced mode. If your scripts load from googletagmanager.com, Google already has the visitor’s location. If they are served through your tagging server, Google’s region-specific settings guide adds three steps:

  1. Send location headers from your hosting to the tagging server.
  2. Enable the built-in Visitor Region variable in the server container, or create a user-defined one if your host uses custom headers.
  3. In the Google Tag Manager: Web container client, tick “Enable region-specific settings” and put that variable in the Region field.

To check it, open the claimed GA4 client in Preview, set Display Variables to values, and look at Region. A country code is right. undefined means the location headers aren’t reaching the container.

If conversions dropped the day the banner went live, the server is probably not the place to look. Start with Consent Mode v2 didn’t lose your conversions. If the server container has other faults too, the wider job is on server-side tracking.

Common questions

No. Google says you set Consent Mode up in the web container only. The Google tag passes the visitor’s consent state to the server container with each request, and Google’s server tags adjust to it. What you do add server-side is a consent condition on every non-Google tag.

Why does my Meta tag fire in server-side GTM when the visitor declined?

Because nothing tells it not to. Google’s server-side consent handling covers Google’s tags only. A Meta tag triggered on every GA4 event also fires on the cookieless pings advanced Consent Mode sends while consent is denied. A common fix is a trigger condition on an Event Data variable reading x-ga-gcs: matches RegEx ^G11 for advertising consent granted. Google doesn’t document the gcs encoding and says it may change, so confirm the values in Preview first.

It can. Stape says its Meta, TikTok, Snapchat and Pinterest server tags support a Consent Settings checkbox, “Send data if marketing consent is given”, which fires only when the request shows advertising consent. Use one gate, not both, and test it the same way.

Hire someone who can read server Preview’s incoming and outgoing requests, and give them access to both GTM containers and Meta Events Manager. The job is done when a declined session shows every non-Google tag under Tags Not Fired and Meta Test Events shows nothing arriving.

Advanced, if you want Google Ads to model the sales of visitors who declined on your own account’s data. Basic sends nothing until the visitor answers, so the server never sees declined visitors and Google uses a general model. Advanced sends cookieless pings while consent is denied, which allows an advertiser-specific model. Google Ads conversion modelling also needs 700 ad clicks over 7 days per country and domain grouping. Either way, gate the non-Google server tags.

Sources

Read on 3 November 2026:

← back to the reading room