---
title: "Fixing Consent Mode v2 Signals That Won't Update"
canonical_url: https://ot.webclat.com/qa/consent-mode-v2-signal-not-updating
description: "The most common cause is calling gtag('consent','update', ...) before the tag library has loaded and registered a listener - here's how to sequence it correctly and verify it in GTM Preview."
source: Webclat | OneTrust Solutions (OneTrust partner, independent consultancy)
---

# Why doesn't Google Consent Mode v2's ad_personalization/analytics_storage signal update the way I expect?

**Short answer:** Consent Mode v2 signals only take effect on each tag's next request, not retroactively on hits already fired, and the most common cause of a signal appearing not to update is calling `gtag('consent', 'update', {...})` before the base tag library (gtag.js or GTM) has actually loaded and registered a listener for it - the call gets pushed into the dataLayer array, but nothing is listening yet to act on it.

## Why this happens

`dataLayer.push()` calls are just array entries until something reads them; gtag.js and GTM both process the queue once they've initialized, which is why a `default` consent call needs to run synchronously before either library loads, and an `update` call needs to run after the visitor actually interacts with the banner. A race where the CMP's accept/decline handler fires the `update` call before GTM has finished initializing produces exactly this symptom - the push happens, but too early for anything to act on it.

A second common cause is a typo or mismatch in the parameter names themselves - `analytics_storage`, `ad_storage`, `ad_user_data`, and `ad_personalization` are the four recognized keys, and a misspelled or nonstandard key name silently does nothing rather than throwing a visible error.

A third is confusing gtag.js-level consent handling with GTM's own Consent Overview - a GTM container needs each tag's Consent Settings configured (see the related tag-governance page) for tags added through GTM's UI to actually respect an incoming signal; the dataLayer push alone isn't sufficient for those tags.

## Fix it

1. **Confirm the default call runs before anything else loads** - The `consent`, `default` call needs to execute synchronously in the page's initial script (a `beforeInteractive`-equivalent placement), before gtag.js, GTM, or any vendor tag has a chance to load.

   ```
window.dataLayer = window.dataLayer || [];
function gtag(){ dataLayer.push(arguments); }
gtag('consent', 'default', {
  analytics_storage: 'denied',
  ad_storage: 'denied',
  ad_user_data: 'denied',
  ad_personalization: 'denied',
  wait_for_update: 500
});
   ```

2. **Confirm the update call fires from the actual banner interaction handler** - Check that your CMP's accept/decline button handler calls `gtag('consent', 'update', {...})` with the exact four parameter names above - a typo in any key silently no-ops rather than erroring.

3. **Check the wait_for_update timing against your banner's own render delay** - If `wait_for_update` is shorter than however long it actually takes your banner to render and receive a click, tags can fire on the default (denied) state before the update ever arrives - increase the value or confirm the banner renders faster than the timeout.

4. **Separate gtag.js-level consent from GTM's per-tag Consent Settings** - If you're using GTM, confirm each relevant tag has Consent Settings configured under Advanced Settings - a correct dataLayer push updates the signal, but a GTM tag without Consent Settings configured doesn't check that signal at all.

5. **Read resolved state from GTM Preview or Tag Assistant, not just the raw dataLayer array** - The dataLayer array shows you what was pushed; GTM Preview's Consent tab shows you the resolved state GTM is actually applying per tag, which is the signal that actually matters for whether a tag fires.

## How to verify it worked

- Open GTM Preview mode, interact with the consent banner, and check the Consent tab for the exact resolved state of each signal after your choice - a passing result matches what you clicked.
- In the browser console, type `dataLayer` after interacting with the banner and confirm a `consent`, `update` entry appears with the exact key names and values you expect.
- If using GTM, confirm in the tag's own debug entry that it lists the correct Consent Settings and shows fired/not-fired matching the current consent state.

## Related

- [Why did my GA4 user-acquisition/channel data collapse to zero right after turning on Consent Mode?](https://ot.webclat.com/qa/consent-mode-zeroed-out-ga4-acquisition-data)
- [How do I fire a GTM trigger the instant a visitor updates their consent choice, without a page reload?](https://ot.webclat.com/qa/gtm-consent-update-trigger)
- [What's the correct pattern to block GA/GTM/AdSense from loading until the visitor accepts cookies?](https://ot.webclat.com/qa/gate-ga-gtm-adsense-behind-cookie-consent)

Contact: ot@webclat.com | (813) 694-4451 | https://ot.webclat.com/#contact
