Last month I opened a Google Ads account and saw something that should be impossible: one Search campaign reporting a 192.63% conversion rate. Almost two conversions for every click.

It was not a great month. It was a tracking bug, and Smart Bidding had been learning from it.

This post walks through what caused it, how to find it in your own account with a short Google Ads script, and how to fix the GTM side so it does not come back. The account is a real one we manage: an Australian identity services company that takes customer applications on its website. The client is anonymous, so I will not name it.

The numbers that did not add up

October 2026, whole account:

Metric Value
Clicks 1,801
Spend A$4,705.70
Reported conversions 1,859.05
Reported cost per conversion A$2.53
Completed applications (the real goal) 161.07
Real cost per completed application A$29.22

More conversions than clicks, and a cost per conversion more than 10x lower than reality.

Root cause: one conversion action, two settings

When we segmented conversions by action, one action stood out: GA4 form_submit. It recorded 1,669.98 of the 1,859.05 conversions, about 90%.

Two settings combined to cause this:

  1. It was a primary action. Primary actions fill the Conversions column and feed Smart Bidding. Secondary actions are reported but not bid on.
  2. It counted every conversion. Google Ads lets each action count One conversion per click or Every conversion after a click. With Every, a visitor who sends three forms adds three conversions. Every is the default for website actions, so it is easy to miss on a lead account.

Google's own help docs say that if you track more than one action, or count every conversion, your conversion rate "might be over 100%". That is exactly what happened.

The part that matters for anyone who builds tracking: all three campaigns were bidding on a goal that contained form_submit. Two used Target CPA and one used Maximise conversions. The inflated numbers were not just a reporting problem. They were the training data.

Find it in your own account with a Google Ads script

You can catch this in under a minute. Paste the script below into Google Ads > Tools > Bulk actions > Scripts, click Preview (it only reads data, it changes nothing) and check the logs.

It does two things:

  1. Lists every enabled conversion action that is primary and counts every conversion.
  2. Flags campaigns where reported conversions are higher than clicks, and shows which action is responsible.
/** * Conversion inflation check for Google Ads. * Read only: it logs findings and changes nothing. */ function main() { const RANGE = 'LAST_30_DAYS'; // 1) Primary actions that count every conversion after a click const actions = AdsApp.search( 'SELECT conversion_action.name, conversion_action.category, ' + 'conversion_action.counting_type, conversion_action.primary_for_goal ' + 'FROM conversion_action ' + "WHERE conversion_action.status = 'ENABLED'" ); Logger.log('--- Primary actions counting EVERY conversion ---'); while (actions.hasNext()) { const a = actions.next().conversionAction; if (a.primaryForGoal && a.countingType === 'MANY_PER_CLICK') { Logger.log('Review: "%s" (%s)', a.name, a.category); } } // 2) Clicks per campaign const clicks = {}; const clickRows = AdsApp.search( 'SELECT campaign.name, metrics.clicks FROM campaign ' + 'WHERE segments.date DURING ' + RANGE + ' AND metrics.clicks > 0' ); while (clickRows.hasNext()) { const r = clickRows.next(); clicks[r.campaign.name] = Number(r.metrics.clicks); } // 3) Conversions per campaign, split by conversion action const conv = {}; const convRows = AdsApp.search( 'SELECT campaign.name, segments.conversion_action_name, metrics.conversions ' + 'FROM campaign WHERE segments.date DURING ' + RANGE + ' AND metrics.conversions > 0' ); while (convRows.hasNext()) { const r = convRows.next(); const name = r.campaign.name; conv[name] = conv[name] || { total: 0, byAction: {} }; const value = Number(r.metrics.conversions); conv[name].total += value; conv[name].byAction[r.segments.conversionActionName] = value; } Logger.log('--- Campaigns with more conversions than clicks ---'); Object.keys(conv).forEach(function (name) { const c = clicks[name] || 0; if (c > 0 && conv[name].total > c) { const top = Object.entries(conv[name].byAction) .sort(function (x, y) { return y[1] - x[1]; })[0]; Logger.log('%s: %s conversions from %s clicks (%s%%). Biggest action: "%s" with %s', name, conv[name].total.toFixed(2), c, (conv[name].total / c * 100).toFixed(1), top[0], top[1].toFixed(2)); } }); } 

A few notes before you run it:

  • Metric values can come back as strings in scripts, hence the Number() calls.
  • segments.conversion_action_name cannot be combined with metrics.clicks in the same query, which is why the script runs two queries and joins them by campaign name.
  • A campaign above 100% is not always wrong. Ecommerce accounts that count every purchase can legitimately get there. On a lead account, treat it as a red flag until proven otherwise.

Fix the tracking at the source (GTM)

The quick fix in Google Ads is to set the noisy action to secondary. That is what we did on 30 October 2026, and bidding now learns from completed applications, renewal starts and, in the Brand campaign, calls.

But the better long-term fix is to stop counting form submits as success in the first place. A form_submit event fires when someone presses the button, including failed validation, double clicks and resubmits. Fire your conversion only when the server confirms the application was created, and send a unique ID so duplicates can be dropped:

// Run this only after your backend confirms the application was saved, // not on the submit click. function trackApplicationComplete(applicationId) { window.dataLayer = window.dataLayer || []; window.dataLayer.push({ event: 'application_complete', application_id: applicationId // unique per application }); } // Example with fetch fetch('/api/applications', { method: 'POST', body: formData }) .then(function (res) { return res.json(); }) .then(function (data) { if (data && data.id) { trackApplicationComplete(data.id); } }); 

Then in Google Tag Manager:

  1. Create a Custom Event trigger for application_complete.
  2. Create a Data Layer Variable for application_id.
  3. Fire your Google Ads conversion tag on that trigger and map application_id to the Transaction ID field. Google Ads uses the transaction ID to drop duplicate conversions.
  4. In Google Ads, set the lead action to count One conversion per click.

What changed in the numbers

Before (as reported) After (completed applications only)
October conversions 1,859.05 161.07
Cost per conversion A$2.53 A$29.22

The second column looks worse, but it is the truth, and it is what Target CPA should be steering towards. Across August to October the same account delivered 799.83 completed applications at about A$19.35 each, roughly one for every seven clicks.

Quick checklist

  • [ ] Segment conversions by action at least once a month
  • [ ] Lead actions count One per click
  • [ ] Only true success events are primary
  • [ ] Conversions fire on server-confirmed success, not on button clicks
  • [ ] A unique ID is passed as the transaction ID
  • [ ] Run the script above after any tracking change

If you have seen a conversion rate above 100% on a lead account, I would like to hear what caused it in yours. Drop it in the comments.

The full write-up with the campaign-level breakdown and timeline is in our identity services Google Ads case study.

This article was written with the help of AI and checked by me against the live Google Ads account data. Always run the script in Preview first.