Debug Google Consent Mode
One Privacy ships a debug command in the widget. Run it in the browser console on any page where the banner is installed. It reads the real state on the page and tells you whether the Google Consent Mode default command reached your Google tags before they fired.
Use it when Google Analytics or Google Ads report missing consent signals, when you change how scripts load, or after you move tags into a tag manager.
Run the commandβ
- Open the page in Chrome, Firefox, Edge, or Safari.
- Open DevTools (
F12, orCmd+Option+Ion Mac) and pick the Console tab. - Type the command and press Enter:
onePrivacy.debug()
The report prints as a group in the console. The command also returns the report as an object, so you can expand it or copy it into a support ticket.
Read the reportβ
[One Privacy] Consent Mode debug
Consent default: OK (set via dataLayer, dataLayer position 0)
wait_for_update: 500 ms
Consent update: sent at 2026-08-27T22:27:33.206Z for groups "C0001,C0003"
Developer ID: sent
One Privacy script: https://.../live/<projectId>/sdk.js
Consent signals: (table)
Google tag commands in dataLayer: (table)
Google tag scripts on the page: (table)
No Consent Mode issues found.
How to read this report: https://docs.oneprivacy.io/docs/developers/debug-consent-mode
Consent defaultβ
This is the line that matters most. It has three possible values.
| Status | Meaning | What to do |
|---|---|---|
OK | The default command was on the page before any Google tag command. | Nothing. |
LATE | At least one Google tag command (gtag("js"), gtag("config"), gtag("event"), or the GTM container load) ran before the default command. Those tags fired without a consent state. | See Fix a late default. |
MISSING | No default command was found on the page. | See Fix a missing default. |
DISABLED | Consent Mode is turned off with onePrivacyOptions.googleConsentMode = false. One Privacy sends no commands on purpose. | Nothing, unless you did not intend it. See Turning Consent Mode off. |
The text in brackets tells you where the default came from:
- set via dataLayer, dataLayer position N: the One Privacy script pushed the default into
window.dataLayer.Nis its position in the array. Google tag commands with a lower position ran before it. - set via Google Tag Manager template: the banner was loaded by the One Privacy tag template in Google Tag Manager. The template sets the default inside GTM on the Consent Initialization trigger, so the GTM container load itself does not count as late.
- set via Google Tag Manager: no default was found in
dataLayer, but gtag.js reports that a default exists. Some other tag inside GTM set it.
wait_for_updateβ
The number of milliseconds Google tags wait for the update command before they run with the default state. One Privacy sends 500. See Google Consent Mode v2.
Consent updateβ
Whether the update command was sent, when, and from which cookie categories. One Privacy sends an update as soon as the widget initializes, using the visitor's stored choice, and again each time the visitor changes their choice. not sent yet means the widget has not initialized on this page.
In a region with No banner, the report shows no banner-related lines but the update is still sent, with all four groups (C0001,C0002,C0003,C0004), so every signal reads granted. See Regions without a banner.
Developer IDβ
Whether One Privacy identified itself to Google with its CMP developer ID. Google uses this to attribute the Consent Mode integration to One Privacy. It is sent by the One Privacy script and by the GTM template.
One Privacy scriptβ
The URL of the One Privacy script found on the page. The note in brackets tells you how it got there:
- no note: the snippet is in your HTML.
- loaded by the One Privacy GTM template: the tag template in Google Tag Manager injected it.
- injected by a tag manager: a Custom HTML tag or another tool injected it.
Consent signalsβ
One row per Consent Mode signal.
| Column | Meaning |
|---|---|
signal | The Consent Mode signal name. |
default | The value sent in the default command. |
update | The value sent in the most recent update command. |
appliedByGoogleTag | The value gtag.js or GTM holds internally for this signal after it processed the commands. null when no Google tag library is loaded on the page. |
default and update show what One Privacy sent. appliedByGoogleTag shows what Google's tag library accepted. If they differ, the tag library loaded before the command reached it, or a regional default did not match the visitor.
The four signals Google requires from a CMP are ad_storage, analytics_storage, ad_user_data, and ad_personalization. One Privacy also sends functionality_storage, personalization_storage, and security_storage. See the mapping in Google Consent Mode v2.
Google tag commands in dataLayerβ
Every gtag command and GTM container load found in window.dataLayer, with its position. Compare the positions with the default's position to see what ran first.
Google tag scripts on the pageβ
Every <script> that loads gtag.js or a GTM container, with the tag ID, the host it loaded from, and its load timing from the browser's Performance API. gtgCandidate: true marks a script served from your own domain instead of googletagmanager.com. That is the pattern of Google tag gateway.
Issuesβ
Each problem prints as a warning with a code and a link to the page that explains the fix.
| Code | Meaning |
|---|---|
LATE | A Google tag command ran before the consent default. |
MISSING | No consent default on the page. |
GTG_CANDIDATE | A Google tag is served from your own domain. Load order is then controlled by the gateway, not by your page. |
DISABLED | Consent Mode commands are turned off by the page option or the template checkbox. |
TAG_MANAGER_ORDER_UNVERIFIED | The script was injected by a tag manager without the One Privacy template. The report cannot see the order of tags fired inside the container; make sure the tag uses the Consent Initialization trigger. |
SCRIPT_NOT_FOUND | The One Privacy script tag was not found. |
Live loggingβ
The report is a snapshot. To watch the commands as they happen, turn on live logging for the current tab:
onePrivacy.debug(true)
Or open the page with ?onePrivacyDebug=1 in the URL. From then on, every page load in that tab logs each consent update as it is sent and prints a full report one second after the page finishes loading. Turn it off with onePrivacy.debug(false) or ?onePrivacyDebug=0. The setting lives in sessionStorage, so closing the tab clears it.
Fix a late defaultβ
A LATE status means a Google tag ran before the default command. Work through these steps in order.
1. Check whether the late tag is loaded through Google tag gateway. This is the first thing to verify, because it changes the fix. Look at the Google tag scripts on the page table. A tag with gtgCandidate: true, or a GTG_CANDIDATE warning, is served from your own domain. Confirm it in Google Ads, Google Analytics, or Google Tag Manager as described in Google tag gateway and load order. If the tag uses Google tag gateway, follow the options on that page. Your page cannot control the load order of a gateway-injected tag, so moving the snippet will not help.
2. If the tag is not on Google tag gateway, move the One Privacy snippet above it. The snippet must be the first script in <head>, before every gtag.js snippet and before the GTM container snippet. See Getting your script.
3. If you load One Privacy through Google Tag Manager, use the One Privacy tag template. Set its trigger to Consent Initialization - All Pages. A Custom HTML tag on All Pages or Initialization fires after the container load, which the report counts as late.
4. Run onePrivacy.debug() again in a fresh browser session and confirm the status is OK.
Fix a missing defaultβ
A MISSING status means no default command exists on the page.
- Check that the One Privacy script is actually installed. A
SCRIPT_NOT_FOUNDwarning next to it confirms it is not. See Verifying the banner is live. - Check that nothing on the page resets
window.dataLayer. A script that runswindow.dataLayer = []after One Privacy loads discards the default. - If the banner loads through Google Tag Manager, check that the One Privacy tag is published and that its trigger fires on this page.
Check with Google's toolsβ
Google's Tag Assistant shows the consent state each tag saw when it fired. Use it as a second check after the One Privacy report. See Troubleshoot consent mode with Tag Assistant and Troubleshoot consent mode.
Still stuck?β
Copy the report object the command returns and send it to google-support@oneprivacy.io, with cmp-support-helper@google.com in CC. See Contacting support. Start with One Privacy support for missing Consent Mode signals, not Google; we work with Google when a problem is on their side.