Paste a crawler user agent from your access log and, if you have it, the IP address on the same line. The string gets checked for the structural mistakes that give away a copy-paste impersonation — wrong capitalisation, a missing operator contact, no version. Then the address gets checked against what that operator actually publishes. Only the second one can settle it, and this page is clear about which is which.
Quick Answer: Can You Tell a Fake Bot From Its User Agent?
Not on its own. A user agent is text the client writes about itself, so a careful impersonator writes a perfect one. Sloppy ones give themselves away through capitalisation and a missing operator contact — but only the IP address settles it.
Jessica Wright
Cybersecurity Threat Researcher
Jessica works on bot verification and IP reputation, separating traffic that is what it says from traffic that only claims to be.
Building this one changed how it works. The obvious design is to store each operator's official user agent and compare exactly — and then you go looking for those official strings and find that three respected 2026 crawler references give three different answers for ClaudeBot, and two different versions for GPTBot. Whichever one you picked, you would be flagging genuine crawlers the moment your copy drifted.
So this checks the shape of a string rather than its exact text, and it never turns that into a verdict. Google writes Googlebot with a lower-case b and Microsoft writes bingbot entirely lower case; a request that gets those wrong was not generated by their software. That is a real signal and it is still not proof, because the careful impersonators get the string perfect. Only the address decides, which is why the IP field sits right beside the string and why the page keeps saying so.
Last reviewed 24 August 2026 · 20 crawler signatures · Vendor ranges read live · Nothing you paste is stored
View all articles by Jessica WrightBecause a user agent string is a sentence the visitor writes about itself. It is an HTTP request header, set by whoever made the request, and nothing in the protocol checks it against anything. Sending Googlebot/2.1 from a laptop is one command-line flag.
That is worth saying plainly because most tools that read a user agent string are parsers: paste one in and they tell you it is Chrome 131 on Windows 11. Useful, and it answers a different question. A parser reports what the string says. This page is about whether the string is telling the truth, and those come apart the moment somebody has a reason to lie.
Imperva's write-up on Googlebot impersonation splits the impersonators into two groups, and the split is useful. The crude ones copy-paste the string into a script — often, in Imperva's words, with obvious mistakes. The sophisticated ones produce requests that look identical to the original and can fool the naked eye.
Those obvious mistakes are what the structural checks above look for, and they cluster in a few places:
Googlebot with a lower-case b. Microsoft writes bingbot entirely lower case. A string that capitalises them differently did not come from the operator's own software.+http://www.google.com/bot.html, or Anthropic's contact email. Retyping from memory loses it.compatible token reads as somebody who edited their browser's string rather than reproduced a crawler's.There is a single exception to all of this. A string that names two different operators — Googlebot and bingbot in the same line — was assembled by somebody. No genuine crawler identifies itself as two companies at once, and no amount of context makes that innocent. It is the only finding on this page that does not need the address to back it up, and this tool raises it above everything else when it appears.
Everything else is not proof, in either direction. A perfect string costs an impersonator one copy-paste, so cleanliness means nothing. And an operator can change its format tomorrow, which would make a genuine crawler look sloppy. That is why every observation on this page is labelled as something to look at rather than as a finding.
Plenty of automated traffic does not pretend to be a crawler. It arrives as curl, python-requests, Go-http-client, Scrapy, or a headless browser that still carries HeadlessChrome in its string. None of that is suspicious by itself — monitoring, uptime checks and legitimate integrations all look like this — but it is automation, and it is not claiming to be anyone in particular.
This page names those when it sees them, so a string that is not a crawler still gets an answer rather than a shrug. What it will not do is turn into a browser parser: identifying Chrome 131 on Windows 11 is a different job with better tools for it.
Which leaves exactly one thing that cannot be written by the sender.
It means the request said it was a particular crawler and arrived from an address that crawler's operator does not publish. The sender controls the string. It does not control which address the packets came from, and it certainly does not control what Google, Microsoft or OpenAI publish about their own infrastructure.
That asymmetry is the whole basis of crawler verification, and it is why the IP address field on this page carries the verdict while the string only carries observations.
| What you see | What it means | How strong |
|---|---|---|
| Claim matches the address | The string says Googlebot and the address is in Google's crawler ranges, or forward-confirms by reverse DNS. | Conclusive |
| Claim contradicts the address | The string says Googlebot and the address is in none of Google's crawler ranges, and reverse DNS does not confirm. | Strong, not absolute — lists go stale |
| Operator publishes nothing | ByteDance and Meta publish neither ranges nor a reverse-DNS scheme. | Unverifiable, which is not the same as fake |
| No IP supplied | Only the string was checked. | Not a verdict at all |
Both halves come from the same access log line, and they have to come from the same one. In a standard Apache or nginx combined line the address is the first field and the user agent is the last quoted one. Pairing an address from one request with a string from another produces a confident answer to a question nobody asked, and it is an easy mistake to make when you are scrolling.
The scale of the mismatch problem is measurable. HUMAN Security tracked sixteen well-known AI crawler user agents over two weeks and found 5.7% of the traffic carrying them was forged, rising to 16.7% for the ChatGPT-User string. One request in six claiming to be that agent was not.
Once you have a mismatch, the address is the lead, not the string. An ASN lookup names the network the request really came from, and that is the durable thing — whoever is doing this can change addresses in seconds but not networks. A blacklist check tells you whether that address already has a reported abuse history.
If you have a whole log rather than one line, checking them individually is not a plan. The bulk checker takes 200 addresses at once and collapses the verified ones into a prefix allowlist. And for the full two-check treatment on a single address across nineteen operators, the universal bot verifier covers it.
This one is worth its own section because it silently reverses the answer, and a lot of hand-written verification scripts have it backwards.
Google publishes more than one address list. There are the crawler files — common-crawlers.json and its siblings, covering Googlebot and the other search crawlers. And there is goog.json, a much broader list of all address space Google announces.
goog.json includes Google Cloud customer addresses. So a scraper running on a Google Cloud virtual machine, sending a forged Googlebot string, sits inside goog.json and passes a check written against it. The same request fails against the crawler files, which is the correct answer. Checking the broad list does not just weaken the test — it inverts it for exactly the traffic you most want to catch.
This page checks the crawler files. So does the Googlebot verifier, which goes further and tells you which of Google's five crawler categories an address belongs to — a distinction that matters because Googlebot and a user-triggered fetcher are different decisions.
Google is not the only operator with more than one list. OpenAI publishes four, with prefixes that overlap between them, so an address can be in GPTBot's file and OAI-SearchBot's at once. Anthropic publishes one file covering three separate agents. Perplexity publishes two that share nothing. Which file you check changes what the answer means, and the GPTBot verifier and the ClaudeBot verifier each cover their operator's arrangement properly.
A user-agent checker invites more confidence than it deserves, so these matter more here than on most pages.
A perfectly formed user agent costs an impersonator one copy-paste. Passing every structural check means the string was copied carefully, and nothing more than that.
Published references disagree on ClaudeBot's string and on GPTBot's version. Comparing against a stored value would report genuine crawlers as spoofed whenever the stored copy drifted, so structure is checked instead.
ByteDance and Meta publish no ranges and no reverse-DNS scheme, so their crawlers are unverifiable by anyone outside those companies. Unverifiable is not fake, and only one of those justifies a block.
A string naming a crawler this page does not track comes back as no recognised claim. That means unknown to this tool, not fabricated, and there are far more crawlers than twenty.
Request rate, which paths were hit, whether robots.txt was fetched first — all invisible here and all more informative than a header. A verified crawler can still be a problem.
The address and the string must come from the same log line. Pairing an address with a user agent from a different request produces a confident answer to a question nobody asked.
Once you have decided what to allow and what to turn away, the crawler blocker writes robots.txt and firewall rules from the same live vendor ranges.
And the guide to IP spoofing covers why a header is never identity in the first place.
A user agent string is an HTTP request header the client sends to describe itself — browser name, version, operating system, or in a crawler’s case its own name and a link to its documentation. Nothing in the protocol verifies it. The server receives whatever the client chose to send, which is why a string saying Googlebot is a claim rather than a fact.
You cannot, from the string alone — and any tool that says otherwise is selling certainty it does not have. A user agent is a line of text the client writes about itself, so a careful impersonator produces a perfect one. What settles it is the IP address the request arrived from: paste both above and this page checks the address against the operator’s published ranges and, where documented, forward-confirmed reverse DNS.
That the request claimed to be a specific crawler and arrived from an address that crawler’s operator does not publish. It is the strongest signal available that a request is not what it says. It is not quite proof — published lists go stale and some operators publish nothing at all — but for Google, Microsoft and OpenAI it is about as close as an outside observer gets.
Because the published references disagree with each other. Three well-regarded 2026 crawler references give three different “official” strings for ClaudeBot, and two different versions for GPTBot. A tool doing exact comparison against any one of them would report genuine crawlers as spoofed as soon as its copy drifted. This page checks structure instead — token spelling, operator contact, version shape — and reports every finding as worth a look rather than as a verdict.
It is a genuine signal and not proof. Google writes Googlebot with a lower-case b, and Microsoft writes bingbot entirely lower case, so a request that capitalises them differently was not generated by the operator’s own software. What it does not tell you is intent — a monitoring script written by someone in your own company can get the capitalisation wrong too.
Partly. Apple, Amazon and Yandex publish no range file, so an address cannot confirm those claims, but all three document a reverse-DNS scheme and this page runs it. ByteDance and Meta publish neither, so their crawlers cannot be verified by anyone from outside. That is a fact about those operators rather than a finding about your visitor.
Because goog.json lists all address space Google announces, including Google Cloud customers. A scraper running on a Google Cloud virtual machine sits inside that list, so a check against it returns a pass for traffic that has nothing to do with Googlebot. The crawler-specific files are the ones to use, and they are what this page checks. This trips up a lot of hand-written verification scripts.
No. It means the string is well formed, which costs an impersonator nothing. It also says nothing about behaviour — a fully verified crawler can still be hitting you hard enough to cause problems, and the answer to that is a crawl-rate setting rather than a block.
In a standard Apache or nginx combined log line it is the last quoted field, after the referrer. The IP address is the first field on the same line. You need both, and they must come from the same line — pairing an address with a user-agent from a different request is how people arrive at confident wrong answers.
This page starts from the string. These start from the address.
Browse the full set on the TrustMyIP tools directory.
A forged string tells you somebody borrowed a name. The address tells you who they actually are, and that is the part worth acting on.
Last updated 24 August 2026 · 20 crawler signatures · Vendor ranges read live · Nothing you paste is stored