Paste the script into Google Ads, authorize once, click Preview, and read the Logs. It prints every negative that is blocking an enabled keyword, where that negative lives, and what it is blocking. It also flags one pairing Google's own script will never show you. It cannot see the account-level negative list, because no script can.
What It Reports
For each enabled keyword in each enabled campaign, the script checks every negative that can physically reach it. A negative on an ad group only reaches that ad group. A campaign negative reaches that campaign. A shared list reaches whichever campaigns the list is attached to.
Anything that collides gets printed with the negative, its match type, the level it sits at, and the keyword it is switching off.
This is the failure with no error attached. A keyword blocked by one of your own negatives still reads as Eligible in the interface. It shows no warning, no status change and no alert. It looks exactly like a keyword nobody is searching for.
The Column No Other Script Has
Every free conflict script in circulation, including the one Google published and has since withdrawn from its own documentation, inherits the same matching rule: if the negative uses a stricter match type than the keyword, the pair is skipped before any text is compared.
So an exact match negative sitting on a phrase or broad keyword never appears in a conflict report. Google's reasoning holds on its own terms, since the keyword carries on serving longer queries.
The counter-argument is the one this script takes. The single query being blocked is usually the highest-intent query that keyword will ever match. Somebody typing your term exactly, with nothing else around it, is the closest thing to a buyer the keyword will see. This script reports that pairing and labels it, rather than deciding on your behalf that it does not matter.
Installing It
In Google Ads, open Tools, then Bulk actions, then Scripts.
Click the plus button, then paste the whole file in, replacing the sample code that is already there.
Click Authorize and accept. One prompt, no tick boxes.
Click Preview, then open the Logs tab underneath to read the results.
Preview is enough. The script writes nothing, so running it in preview gives exactly the same output as running it for real. There is no reason to schedule it until you want the check repeated.
About That Authorization Prompt
Google will tell you the script can edit and delete your campaigns. That is true of every Google Ads script, because there is no read-only permission level to ask for. The prompt describes what a script of this kind could do, rather than what this one does.
The only real check is the code, which is why it is on this page rather than behind a download. Search it for remove, create and set. You will not find a call that changes anything in your account.
You will also not find SpreadsheetApp, MailApp or UrlFetchApp. Google grants permissions by scanning what the code mentions rather than what it runs, so an unused spreadsheet feature costs the same extra authorization prompt as a used one. Stripping them is what reduces this to a single prompt with nothing to tick.
The Script
Loading the script...
What It Cannot See
The account-level negative keyword list. That is the fourth place negatives live in a Google Ads account, and no script can read it.
It is also the one that matters most when something goes wrong there. An account-level negative reaches every campaign you run, including campaigns that do not exist yet, so a term added to it in 2023 is still switching off keywords in campaigns built years later. Nothing in the interface connects those two events.
Check one campaign without installing anything
Export your negative keywords and your keywords from Google Ads, drop both files in, and see which negatives are blocking keywords you are still bidding on. Runs in your browser, no signup, nothing sent to a server.
Open the free conflict checkerWhere This Script Stops
It answers one question, once, for one account, at the moment you run it.
| This script | SearchSavior | |
|---|---|---|
| Ad group, campaign, shared lists | Yes | Yes |
| Account-level negative list | No | Yes |
| Which match type clears each conflict | No | Yes |
| Checks a negative before it goes in | No | Yes |
| Fix it from the result, and undo | No | Yes |
| Runs across every client account | One per install | Yes |
If you run one account, the script is probably all you need. At a dozen accounts it means a dozen installs, a dozen authorizations and a dozen sets of logs to read, which is the point at which people stop doing it.
Read Every Negative in Every Account, Daily
SearchSavior checks all four levels, tells you which match type clears each conflict rather than only telling you to delete, and reverses anything you apply. Free for 7 days, no card.
Start a free trialFrequently Asked Questions
Is there a free script to find negative keyword conflicts in Google Ads?
Yes. The script on this page reads every negative keyword in an account at ad group, campaign and shared list level, compares each one against your enabled keywords, and prints the ones that are blocking keywords you are still paying for. It is free, the full code is on the page, and it runs inside Google Ads with no account to create.
Does the script change anything in my Google Ads account?
No. It only reads. There is no call anywhere in it that creates, removes or changes a keyword, a negative, a campaign or a setting. You can confirm that yourself by searching the code for remove, create and set before you run it.
Why does Google ask for permission to edit and delete my campaigns?
Google Ads scripts have no read-only permission level. Every script gets the same authorization prompt regardless of what it does, so the prompt describes what a script could do rather than what this one does. Reading the code is the only real check, which is why the full code is published here rather than hidden behind a download.
What does the script not check?
The account-level negative keyword list. That is the fourth place negatives live in Google Ads, it reaches every campaign in the account including ones created later, and no Google Ads script can read it. A negative sitting there blocking a live keyword will not appear in these results.
Does Google's own script find the same conflicts?
Not all of them. Google's matcher stops before comparing any text whenever the negative uses a stricter match type than the keyword, so an exact match negative sitting on a phrase or broad keyword is never examined. This script reports that pairing and flags it, because the single query being blocked is usually the highest-intent query that keyword will ever match.