Skip to main contentSkip to footer

Verification Methods

Four checks carry most of the weight in the free tools: forward-confirmed reverse DNS, crawler verification, RDAP prefix matching and blacklist queries. Each of them has a shortcut that looks correct in testing and produces wrong answers in production. This page states what the tools do instead, in enough detail to reproduce it.

Forward-confirmed reverse DNS

A PTR record proves nothing on its own. Whoever controls an address block decides what name it carries, and nothing stops that name being mail.yourbank.com. The check that carries weight is forward confirmation: resolve the PTR name back and see whether the original address is among the results.

Compare the whole address set, not the first record

The common error is to compare against the first A record returned. Addresses behind a round-robin name break that immediately:

text
8.8.8.8  ->  PTR dns.google
             ->  A     8.8.8.8, 8.8.4.4
             ->  AAAA  2001:4860:4860::8888, 2001:4860:4860::8844

8.8.4.4  ->  PTR dns.google
             ->  same four addresses

A tool that stops at the first answer reports 8.8.4.4 as unconfirmed, because DNS returned 8.8.8.8 first. Roughly every second query against a round-robin name comes out wrong that way. Both the A and the AAAA set have to be resolved and searched.

Compare addresses in binary form

The second error is comparing addresses as strings. 2001:db8::1 and 2001:0db8:0000:0000:0000:0000:0000:0001 are the same address and share no characters; ::ffff:192.0.2.1 and 192.0.2.1 are the same address in two families. Both comparisons belong on the packed form that inet_pton() returns, never on the text.

What a failure means

ResultWhat it says
ConfirmedThe PTR name resolves back to this address. The operator of the name and the operator of the address agree.
No PTR recordNothing to check. Common on cloud instances, and the usual reason a mail server is refused before the message body is sent.
Not confirmedA PTR name exists but does not resolve back. Either a stale record or a name someone set without controlling the forward zone.

Try it on Reverse DNS.

Verifying a crawler

A User-Agent header is free text that any client can send, which is why every large operator publishes a verification method. For two decades that method was forward-confirmed reverse DNS. That is no longer true for half of the crawlers worth checking.

CrawlerOperatorMethod
GooglebotGoogleForward-confirmed reverse DNS
BingbotMicrosoftForward-confirmed reverse DNS
ApplebotAppleForward-confirmed reverse DNS
YandexBotYandexForward-confirmed reverse DNS
BaiduspiderBaiduForward-confirmed reverse DNS
DuckDuckBotDuckDuckGoPublished address ranges
GPTBotOpenAIPublished address ranges
OAI-SearchBotOpenAIPublished address ranges
PerplexityBotPerplexityPublished address ranges
ClaudeBotAnthropicPublished address ranges

The split runs along the line between classic search engines and the generation of AI crawlers. The newer operators document JSON files of address ranges and do not make PTR names part of their method, so an address inside the range OpenAI publishes for GPTBot carries no reverse record at all. A verifier that only knows the DNS method marks every one of them as unconfirmed, which is the same verdict it gives a forgery.

Three verdicts are therefore kept apart:

  • Confirmed. The name belongs to a known crawler and the method that applies to that operator agrees.
  • Not confirmed. There is no PTR record, the forward check failed, or the User-Agent claims a crawler that the evidence does not support. This is the case to act on.
  • Not attributable. Everything resolves cleanly, but the address belongs to no crawler this tool knows. The normal result for an ordinary visitor.

Try it on Bot Verification.

Finding the responsible registry over RDAP

An abuse report sent to the wrong block is the same as no report. A single address usually sits inside a hosting provider's allocation, which sits inside a transit provider's allocation, which belongs to a regional registry. Only the innermost operator can take the machine off the network.

The bootstrap file, not a redirector

There is no central directory of address space. IANA publishes a bootstrap file that maps every allocated prefix to the registry responsible for it, and it is far smaller than most estimates suggest: measured on 2026-09-20, ipv4.json was 5,629 bytes and ipv6.json 1,476 bytes. A cached copy per day serves every visitor, so the lookup talks to the registry directly instead of routing every query through a public redirector.

Longest prefix, not first match

Prefixes overlap. A small range inside an old, large allocation frequently belongs to a different registry than its parent, so the first matching prefix is regularly the wrong one. The match has to be the longest one.

The contact with the abuse role

An RDAP response carries several contact entities, and the first one is usually administrative rather than operational. The address the tool returns comes from the entity that carries the abuse role. If a network publishes none, the result says so rather than falling back to an unrelated contact: the registry and the holder of the block are then the next places to go.

Try it on Abuse Contact, and see IP Delisting for the other direction.

Blacklist queries

The query format

A DNSBL is queried by reversing the address and appending the zone. For IPv4 that is the octets in reverse order; for IPv6, RFC 5782 specifies the nibble format, every hex digit separately and in reverse:

text
192.0.2.1        ->  1.2.0.192.<zone>
2001:db8::1      ->  1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
                     0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.<zone>

Not every list answers for IPv6

Nine of the twelve curated lists publish an IPv6 zone; three do not. Querying an IPv4-only zone for an IPv6 address returns NXDOMAIN, which is indistinguishable from a clean result. Those three are therefore not queried at all for IPv6 and are reported as not applicable, so an empty answer is never presented as a pass.

Which lists answer is verified rather than assumed: every zone in the set replies to the RFC 5782 test entry from this server's resolver. Lists that structurally cannot be queried from a shared resolver are excluded, among them Spamhaus ZEN, which answers a public resolver with a block code instead of a result.

Reading the return code

A hit is signalled by an A record in 127.0.0.0/8, and the exact value carries the reason. One range is not a listing at all: codes in 127.255.255.0/24 are reserved for query errors, a blocked public resolver, an exceeded rate limit or a malformed query. Reading those as a hit turns an infrastructure problem into a false accusation.

AnswerReading
A record in 127.0.0.0/8Listed, the code says why
A record in 127.255.255.0/24Query error, not a listing
NXDOMAIN or NOERROR without an answerNot listed
Timeout, SERVFAIL, REFUSEDList unreachable, no statement either way

Try it on DNSBL Blacklist Check. Our own zone is documented under DNSBL / RBL Zone.

Fetching a page safely

The header check is the only tool that fetches a URL the visitor names, which makes it a server-side request forgery surface. The fetch is restricted accordingly:

  • Only http and https, only ports 80 and 443.
  • The hostname is resolved and every returned address is checked against the private, loopback, link-local, CGNAT and multicast ranges, in both address families.
  • Addresses that carry an IPv4 address inside an IPv6 one are unwrapped before the check: v4-mapped, v4-compatible, NAT64 and 6to4. Missing 6to4 is a documented way around filters of this kind, since 2002:7f00:1:: is loopback and 2002:c0a8:101:: is 192.168.1.1.
  • Redirects are followed manually, at most three times, with the full check repeated on each hop.
  • A hard timeout, and only the first few kilobytes of the body are read.
  • The request uses GET rather than HEAD, because a number of servers answer HEAD with a different header set.

Try it on Security Headers. How the findings turn into a number is described under Tool Scoring.

Last updated: · Maintained by the ReportedIP team

Security Focused
GDPR Compliant
Made in Germany
Back to Docs