Google Ads Troubleshooting & Debugging | Blue Frog Docs

Google Ads Troubleshooting & Debugging

Troubleshooting playbook and diagnostics checklist for Google Ads.

Google Ads Troubleshooting & Debugging

Comprehensive diagnostic guide for resolving Google Ads conversion tracking, tag implementation, and campaign issues.

Symptom Library

Conversion Tracking Issues

  • Conversions not recording - Zero conversions despite traffic
  • Delayed conversions - Conversions appearing 24-72 hours late
  • Conversion value discrepancies - Mismatches with actual revenue
  • Duplicate conversions - Same conversion counted multiple times
  • Partial conversions - Some conversions missing from reports

Tag Implementation Issues

  • Tag not firing - Google Tag not loading on pages
  • Tag firing on wrong pages - Conversion tag on non-conversion pages
  • Multiple tags detected - Duplicate tags causing conflicts
  • gtag.js vs analytics.js conflicts - Legacy tag conflicts
  • Tag Assistant showing errors - Tag implementation errors

Enhanced Conversions Issues

  • Partial match quality - Low match rates for enhanced conversions
  • Missing user data - Customer info not being sent
  • Hashing errors - Incorrect data hashing implementation
  • Consent mode conflicts - Enhanced conversions blocked by consent

Auto-Tagging Issues

Campaign Performance Issues

  • Ad disapprovals - Policy violations blocking ads
  • Low quality scores - High CPCs due to low QS
  • Budget limitations - Campaigns limited by budget
  • Bid strategy not learning - Smart bidding stuck in learning
  • Impression share losses - Missing impressions due to rank/budget

Investigation Workflow

Level 1: Quick Diagnostics (5 minutes)

Step 1: Check Conversion Status

1. Google Ads > Tools > Conversions
2. Check "Status" column:
   - "Recording conversions" (Green) = Working
   - "No recent conversions" (Yellow) = Warning
   - "Unverified" (Red) = Not working
3. Review "Last received" timestamp

Step 2: Tag Assistant Verification

1. Install Google Tag Assistant extension
2. Visit conversion page
3. Click extension icon
4. Verify:
   - Google tag detected (green)
   - Conversion event fires on action
   - No errors or warnings

Step 3: Recent Conversions Check

1. Google Ads > Campaigns
2. Add columns: Conversions, Conv. value
3. Compare last 7 days to prior period
4. Look for sudden drops (>30%)

Level 2: Deep Diagnostics (15-30 minutes)

Tag Implementation Analysis

  1. Inspect Tag Code
<!-- Verify global site tag present -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-123456789"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'AW-123456789');
</script>

<!-- Verify conversion event tag -->
<script>
  gtag('event', 'conversion', {
    'send_to': 'AW-123456789/AbCdEfGhIjKlMnOpQr',
    'value': 99.99,
    'currency': 'USD',
    'transaction_id': 'ORDER_12345'
  });
</script>
  1. Network Request Inspection
1. Chrome DevTools > Network tab
2. Filter: "google-analytics.com/collect" or "googleadservices.com"
3. Trigger conversion action
4. Verify request sent (Status 200)
5. Check request payload includes:
   - Conversion ID
   - Conversion label
   - Value and currency (if applicable)
   - Transaction ID (for deduplication)
  1. DataLayer Validation
// Console check for dataLayer
console.log(window.dataLayer);

// Should show array with events
// Example output:
[
  {0: 'js', 1: Date},
  {0: 'config', 1: 'AW-123456789'},
  {0: 'event', 1: 'conversion', 2: {...}}
]

Conversion Attribution Analysis

1. Google Ads > Tools > Attribution
2. Review attribution model settings
3. Check attribution window:
   - Click-through: 30-90 days
   - View-through: 1-30 days
4. Compare different attribution models

Enhanced Conversions Verification

// Check if enhanced conversions data is sent
gtag('config', 'AW-123456789', {
  'phone_number': '+1234567890',
  'email': 'customer@example.com',
  'address': {
    'first_name': 'John',
    'last_name': 'Doe',
    'street': '123 Main St',
    'city': 'New York',
    'region': 'NY',
    'postal_code': '10001',
    'country': 'US'
  }
});

// Verify data is hashed in network request
// Check DevTools > Network > google-analytics.com/collect
// Look for &em= (hashed email) parameter

Level 3: Advanced Diagnostics (30-60 minutes)

GCLID Capture Testing

// Check if GCLID is being captured
function getGCLID() {
  const urlParams = new URLSearchParams(window.location.search);
  const gclid = urlParams.get('gclid');

  console.log('GCLID present:', !!gclid);
  console.log('GCLID value:', gclid);

  // Check if stored in cookie
  const gclidCookie = document.cookie.match(/gclid=([^;]+)/);
  console.log('GCLID cookie:', gclidCookie?.[1] || 'Not found');

  return gclid;
}

getGCLID();

Offline Conversion Import Testing

1. Create test conversion in Google Ads
2. Use API or manual upload
3. Verify GCLID matches clicked ad
4. Check for import errors in UI
5. Validate conversion appears within 24 hours

Consent Mode Diagnostics

// Check consent mode status
gtag('consent', 'default', {
  'ad_storage': 'denied',
  'analytics_storage': 'denied',
  'ad_user_data': 'denied',
  'ad_personalization': 'denied'
});

// Check current consent state
console.log('Consent state:', window.dataLayer.filter(
  item => item[0] === 'consent'
));

// Update consent after user acceptance
gtag('consent', 'update', {
  'ad_storage': 'granted',
  'analytics_storage': 'granted',
  'ad_user_data': 'granted',
  'ad_personalization': 'granted'
});

Common Issues & Solutions

Issue 1: Conversions Not Recording

Symptoms:

  • Zero conversions in Google Ads
  • Tag fires but no conversions appear
  • "Unverified" status in Conversions page

Diagnostic Steps:

  1. Verify Tag Placement
<!-- WRONG: Event tag without global tag -->
<script>
  gtag('event', 'conversion', {'send_to': 'AW-123456789/AbCdEf'});
</script>

<!-- CORRECT: Global tag + event tag -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-123456789"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());
  gtag('config', 'AW-123456789');
</script>
<script>
  gtag('event', 'conversion', {'send_to': 'AW-123456789/AbCdEf'});
</script>
  1. Check Conversion Action Status
Google Ads > Tools > Conversions
- Status must be "Recording conversions"
- Not "Removed" or "Paused"
  1. Verify Conversion Window
Recent conversions may take up to 3 hours to appear
Offline conversions can take 24-48 hours
Check "All conversions" column (includes modeling)

Solutions:

// Ensure gtag function exists before calling
if (typeof gtag !== 'undefined') {
  gtag('event', 'conversion', {
    'send_to': 'AW-123456789/AbCdEfGhIjKl',
    'value': 1.0,
    'currency': 'USD'
  });
} else {
  console.error('gtag not loaded - conversion not tracked');
}

Issue 2: Conversion Value Discrepancies

Symptoms:

  • Google Ads shows different revenue than actual
  • Values in wrong currency
  • Decimal precision issues

Solutions:

Currency Consistency

// WRONG: Mixed currencies
gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbCdEf',
  'value': 99.99,
  'currency': 'EUR'  // But value is in USD
});

// CORRECT: Match Google Ads account currency
const accountCurrency = 'USD';
gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbCdEf',
  'value': parseFloat(orderTotal.toFixed(2)),
  'currency': accountCurrency
});

Transaction Deduplication

// Prevent double-counting with transaction_id
gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbCdEf',
  'value': 99.99,
  'currency': 'USD',
  'transaction_id': 'ORDER_' + orderId  // Required for deduplication
});

Value Calculation

// Include tax and shipping or not (be consistent)
const subtotal = 100.00;
const tax = 8.00;
const shipping = 5.00;

// Option 1: Transaction value only
const conversionValue = subtotal;

// Option 2: Total including tax/shipping
const conversionValue = subtotal + tax + shipping;

gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbCdEf',
  'value': conversionValue,
  'currency': 'USD',
  'transaction_id': orderId
});

Issue 3: Enhanced Conversions Not Working

Symptoms:

  • "Partial" match quality in Google Ads
  • Low match rates shown in reporting
  • Customer data not being sent

Solutions:

1. Implement Enhanced Conversions

// Method 1: Automatic (recommended)
gtag('set', 'user_data', {
  "email": "customer@example.com",
  "phone_number": "+12345678900",
  "address": {
    "first_name": "John",
    "last_name": "Doe",
    "street": "123 Main St",
    "city": "New York",
    "region": "NY",
    "postal_code": "10001",
    "country": "US"
  }
});

// Method 2: Manual (code mode)
gtag('event', 'conversion', {
  'send_to': 'AW-123456789/AbCdEf',
  'value': 99.99,
  'currency': 'USD',
  'transaction_id': 'ORDER_12345',
  'email': 'customer@example.com',
  'phone_number': '+12345678900',
  'first_name': 'John',
  'last_name': 'Doe',
  'home_address': {
    'street': '123 Main St',
    'city': 'New York',
    'region': 'NY',
    'postal_code': '10001',
    'country': 'US'
  }
});

2. Server-Side Implementation (WordPress)

// Collect user data server-side
function google_ads_enhanced_conversion_data($order_id) {
    $order = wc_get_order($order_id);

    $enhanced_data = array(
        'email' => $order->get_billing_email(),
        'phone_number' => $order->get_billing_phone(),
        'first_name' => $order->get_billing_first_name(),
        'last_name' => $order->get_billing_last_name(),
        'home_address' => array(
            'street' => $order->get_billing_address_1(),
            'city' => $order->get_billing_city(),
            'region' => $order->get_billing_state(),
            'postal_code' => $order->get_billing_postcode(),
            'country' => $order->get_billing_country()
        )
    );

    // Output to dataLayer
    ?>
    <script>
    window.dataLayer = window.dataLayer || [];
    dataLayer.push({
        'event': 'enhanced_conversion_data',
        'user_data': <?php echo json_encode($enhanced_data); ?>
    });
    </script>
    <?php
}
add_action('woocommerce_thankyou', 'google_ads_enhanced_conversion_data');

3. Data Quality Requirements

At minimum, provide ONE of:
- Email (most valuable)
- Phone number
- First name + Last name + Postal code

Format requirements:
- Email: lowercase, trimmed
- Phone: E.164 format (+country code)
- Names: lowercase, no special characters
- Postal code: no spaces
- Country: ISO 3166-1 alpha-2 (US, GB, etc.)

Issue 4: Auto-Tagging Problems

Symptoms:

  • GCLIDs missing from landing page URLs
  • Source showing as "direct" instead of "google/cpc"
  • Offline conversion imports failing

Solutions:

1. Enable Auto-Tagging

Google Ads > Settings > Account settings
Enable "Auto-tagging"

2. Preserve GCLID Across Pages

// Store GCLID on landing
function storeGCLID() {
  const urlParams = new URLSearchParams(window.location.search);
  const gclid = urlParams.get('gclid');

  if (gclid) {
    // Store in sessionStorage
    sessionStorage.setItem('gclid', gclid);

    // Store in cookie (90 days)
    document.cookie = `gclid=${gclid}; max-age=${90 * 24 * 60 * 60}; path=/`;

    console.log('GCLID stored:', gclid);
  }
}

// Retrieve GCLID for conversion
function getStoredGCLID() {
  return sessionStorage.getItem('gclid') ||
         document.cookie.match(/gclid=([^;]+)/)?.[1];
}

// Use on conversion page
const gclid = getStoredGCLID();
if (gclid) {
  // Send with offline conversion import
  console.log('GCLID for conversion:', gclid);
}

3. Handle UTM Parameter Conflicts

// Auto-tagging with manual UTMs
// Google Ads auto-tagging will ADD gclid, not replace UTMs

// If you need both, allow override in Google Analytics
// GA4 config:
gtag('config', 'G-XXXXXXXXXX', {
  'allow_google_signals': true,
  'allow_ad_personalization_signals': true
});

4. Cross-Domain GCLID Passing

// Configure linker for cross-domain tracking
gtag('set', 'linker', {
  'domains': ['example.com', 'checkout.example.com'],
  'accept_incoming': true
});

// Or for specific links
gtag('set', 'linker', {
  'domains': ['checkout.example.com']
});

// Manually decorate links
function decorateLink(url) {
  if (typeof gtag !== 'undefined') {
    return gtag('linker:decorate', url);
  }
  return url;
}

Issue 5: Ad Disapprovals

Common Policy Violations:

1. Destination Mismatch

Issue: Ad goes to different URL than display URL
Solution:
- Ensure display URL matches domain of final URL
- Check for redirects changing domain
- Update display URL to match final destination

2. Malicious or Unwanted Software

Issue: Site flagged for malware
Solution:
- Run Google Safe Browsing check
- Scan site with security tools
- Request review after cleanup

3. Circumventing Systems

Issue: Cloaking or misleading content
Solution:
- Ensure ads and landing pages are consistent
- No hidden text or misleading redirects
- Same content for all users/bots

4. Restricted Content

Issue: Prohibited products or services
Solution:
- Review Google Ads policies
- Remove restricted content
- Request certification if applicable (e.g., healthcare)

Issue 6: Low Conversion Rates

Diagnostic Questions:

  1. Is the conversion action correctly defined?

    • Check: Does it match actual conversion goal?
    • Fix: Redefine conversion action if needed
  2. Is the tag firing on the right page?

    • Check: Tag Assistant on conversion page
    • Fix: Move tag to correct page (thank you page)
  3. Are conversions being counted correctly?

    • Check: "Every" vs "One" counting method
    • Fix: Change to "One" for purchases, "Every" for page views
  4. Is attribution window appropriate?

    • Check: 30-day click, 1-day view (default)
    • Fix: Extend for longer sales cycles

Debugging Tools

Google Tag Assistant

Installation & Use:

1. Install Chrome extension
2. Navigate to any page on your site
3. Click extension icon
4. View tag status:
   - Green = Working correctly
   - Yellow = Minor issues
   - Red = Critical errors

Tag Assistant Connect Mode:

1. Enable "Connect"
2. Perform actions on site
3. View recorded events
4. Check data being sent
5. Validate conversion fires

Conversion Tracking Status:

Google Ads > Tools > Conversions
Check status indicators:
- "Recording conversions" = Active
- "Unverified" = Tag not detected
- "No recent conversions" = Tag working but no conversions

Tag Installation Test:

1. Tools > Conversions
2. Select conversion action
3. Click "Tag setup" > "Install the tag yourself"
4. Click "Test your tag"
5. Visit conversion page in new tab
6. Verify "Tag is working" message

Chrome DevTools Network Analysis

Request Inspection:

1. F12 > Network tab
2. Filter: "collect" or "google"
3. Trigger conversion
4. Find request to google-analytics.com/collect
5. Check payload includes:
   - tid=AW-123456789 (tracking ID)
   - ec=conversion (event category)
   - ea=conversion_label (event action)
   - ev=value (event value)
   - cu=currency (currency code)

GTM Preview Mode

For GTM Implementations:

1. Google Tag Manager > Preview
2. Enter your website URL
3. Perform actions
4. Check:
   - Tags firing on correct triggers
   - Data layer variables populated
   - Google Ads conversion tag fires
   - No errors in debug panel

GA4 DebugView

For GA4-Linked Conversions:

1. Google Analytics 4 > Configure > DebugView
2. Enable debug mode:
   gtag('config', 'G-XXXXXXXXXX', {debug_mode: true});
3. View real-time events
4. Check conversion events
5. Validate parameters

Monitoring & Alerts

Automated Monitoring Setup

1. Conversion Volume Alerts

// Daily check for conversion drops
function checkConversionDrop() {
  const today = getConversions('today');
  const yesterday = getConversions('yesterday');
  const lastWeek = getConversions('last_7_days') / 7;

  const dropFromYesterday = (yesterday - today) / yesterday;
  const dropFromAverage = (lastWeek - today) / lastWeek;

  if (dropFromYesterday > 0.5 || dropFromAverage > 0.3) {
    sendAlert({
      type: 'Conversion Volume Drop',
      today: today,
      yesterday: yesterday,
      average: lastWeek,
      dropPercent: Math.max(dropFromYesterday, dropFromAverage) * 100
    });
  }
}

2. Tag Health Monitoring

// Check if tags are loading correctly
function monitorTagHealth() {
  const checks = {
    gtagLoaded: typeof gtag !== 'undefined',
    dataLayerExists: typeof window.dataLayer !== 'undefined',
    googleAdsTagPresent: !!document.querySelector('script[src*="googletagmanager.com/gtag"]'),
    recentErrors: window.dataLayer?.filter(item =>
      item[0] === 'error'
    ).length || 0
  };

  const issues = Object.entries(checks)
    .filter(([key, value]) => !value || value > 0)
    .map(([key, value]) => ({ check: key, status: value }));

  if (issues.length > 0) {
    console.error('Tag Health Issues:', issues);
    sendAlert({ type: 'Tag Health', issues });
  }

  return checks;
}

// Run on every page load
monitorTagHealth();

3. Enhanced Conversion Match Quality

Setup in Google Ads:
1. Tools > Conversions
2. Select conversion action
3. Check "Match quality" metric
4. Set alerts for drops below "Average"

Performance Benchmarks

Metric Target Warning Critical
Tag Load Time under 1s under 3s over 5s
Conversion Latency under 3 hours under 24 hours over 48 hours
Match Quality High Average Low
Tag Fire Rate 99%+ over 95% under 95%
GCLID Capture Rate 99%+ over 95% under 90%

Best Practices

Implementation Checklist

  • Global site tag on all pages
  • Conversion event tag only on conversion pages
  • Transaction IDs for deduplication
  • Currency and value tracking correctly
  • Enhanced conversions enabled
  • Auto-tagging enabled in Google Ads
  • GCLID preservation implemented
  • Consent mode configured (if EU traffic)
  • Conversion window appropriate for business
  • Attribution model reviewed
  • Tag Assistant shows no errors
  • Conversions verified in Google Ads
  • Team trained on troubleshooting

Code Examples

Complete Conversion Tracking Setup:

<!-- Global site tag (gtag.js) - Google Ads -->
<script async src="https://www.googletagmanager.com/gtag/js?id=AW-123456789"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  // Configure account
  gtag('config', 'AW-123456789');

  // Enhanced conversions (if applicable)
  gtag('set', 'user_data', {
    "email": "customer@example.com",
    "phone_number": "+12345678900",
    "address": {
      "first_name": "John",
      "last_name": "Doe",
      "city": "New York",
      "region": "NY",
      "postal_code": "10001",
      "country": "US"
    }
  });
</script>

<!-- Conversion Event Tag (on thank-you page only) -->
<script>
  gtag('event', 'conversion', {
    'send_to': 'AW-123456789/AbCdEfGhIjKlMnOp',
    'value': 99.99,
    'currency': 'USD',
    'transaction_id': 'ORDER_12345'
  });
</script>

Dynamic Value Tracking:

<script>
  // Get order value from page
  const orderValue = parseFloat(document.getElementById('order-total').innerText);
  const orderId = document.getElementById('order-id').innerText;

  // Track conversion with dynamic value
  gtag('event', 'conversion', {
    'send_to': 'AW-123456789/AbCdEfGhIjKlMnOp',
    'value': orderValue,
    'currency': 'USD',
    'transaction_id': orderId
  });
</script>
// SYS.FOOTER