DEV Community

Merlonix
Merlonix

Posted on Originally published at merlonix.com

Is My Domain Blacklisted? Why a Public DNSBL Check Can Show a False Positive

Originally published on the Merlonix blog.

A DNS blocklist (DNSBL, sometimes RBL) is a published list of IP addresses a provider has flagged as a source of spam. Mail servers consult these lists in real time: if the IP that just connected is listed, the message is usually rejected outright or filed to spam. A single listing on a widely-consulted list — Spamhaus, SpamCop, Barracuda, UCEPROTECT — can quietly kill a large share of your mail, including the transactional kind you can least afford to lose: password resets, receipts, alerts.

So "am I blacklisted?" is a reasonable thing to check. The trap is that the free tools answering it can be wrong in the direction that scares you — they can report you as listed on the biggest, scariest list when you're not. Not because the tool is broken, but because of how DNSBLs answer a query, and where the tool is querying from.


How a DNSBL lookup actually works

A blocklist isn't an API — it's a specially-shaped DNS zone. To ask "is 192.0.2.10 listed on bl.spamcop.net?" you reverse the IP's octets, append the list's zone, and resolve an A record:

10.2.0.192.bl.spamcop.net   →   A?
Enter fullscreen mode Exit fullscreen mode

The answer is the result:

  • An address in 127.0.0.0/8 means listed — and the exact 127.0.0.x value is a reason code (which sub-list, why).
  • NXDOMAIN (no such name) means not listed — a definitive clean answer.
  • A timeout or SERVFAIL means inconclusive — you didn't get an answer, which is not the same as "clean."

That three-way split — listed / clean / inconclusive — is the whole game, and it's where naive checkers go wrong. Collapsing it to a two-way "got a 127.x answer = listed, otherwise fine" is the bug.

The sentinel that trips naive checkers

Here's the part almost no "free blacklist check" page tells you: several of the largest blocklists refuse to answer queries that arrive through a big shared or public resolver — Cloudflare's 1.1.1.1, Google's 8.8.8.8, and the like. Spamhaus and Barracuda both do this. The lists are funded by paid data feeds, and they don't want to serve free bulk lookups riding in on a public resolver's IP.

The critical detail is how they refuse. They don't return NXDOMAIN and they don't time out. They return a listing — an A record in 127.255.255.0/24. Spamhaus's 127.255.255.254, for example, documents as "query via public/open resolver". It looks exactly like a hit, because structurally it is a 127.x answer. It just doesn't mean "this IP is a spammer" — it means "I'm not answering you here."

Now put that together with where a free checker runs. A browser-based tool, a serverless function, most cloud runtimes — they egress DNS through a public resolver. So the query that's supposed to check your reputation on Spamhaus comes back 127.255.255.254, and a tool that treats any 127.x as "listed" tells you: you're on Spamhaus. You're not. You just asked from the wrong place.

That's the false positive, and it's the worst kind — it points at the highest-stakes list, so it's the one most likely to send someone into a delisting panic over a listing that was never real.

The fix is to classify, not just detect

The honest handling is to keep the third state and use it. A listing code is a 127.x answer minus the 127.255.255.0/24 sentinel block:

  • 127.0.0.x (and the rest of 127.0.0.0/8 below the sentinel) → a real listing, carry the reason code and the delisting link.
  • 127.255.255.xnot a listing — it's "blocked / query via public resolver." Record it as inconclusive, never as listed.
  • NXDOMAIN → clean for that list.
  • timeout / SERVFAIL / anything else → inconclusive for that list.

A list that only ever answers the sentinel from your vantage point simply contributes no signal — which is correct. It's better to say "I couldn't get a definitive answer from Spamhaus" than to invent a listing. And the aggregate verdict has to respect that too: report listed only when a real code came back, clean only when at least one list gave a definitive answer and nothing was listed, and inconclusive when every lookup errored or was blocked. "I don't know" is a valid, honest result.

Which lists still carry real signal from a public resolver

Not all of them refuse. A handful of well-run free lists — SpamCop, UCEPROTECT-1, Mailspike, PSBL, DroneBL, and GBUdb Truncate among them — answer public-resolver queries for real, so a check from a public vantage point still gets a trustworthy result from them. (You can confirm a list is answering with its documented test entry: the standard 127.0.0.2 probe should come back listed and a 127.0.0.1 canary should come back NXDOMAIN. If both look the same, the list isn't really answering you.)

So a public one-off check isn't useless — it's just partial. It can give you a solid read from the lists that answer, and an honest "inconclusive" from the ones that don't, instead of a confident wrong answer. What it can't do is give you Spamhaus's real verdict, because Spamhaus won't tell a public resolver.

What to do with a "listed" result

If a check reports a real listing (a 127.0.0.x reason code from a list that answers):

  1. Confirm it from the right place. Query the list's own web lookup — check.spamhaus.org, Barracuda's reputation lookup — from your own network, or check from the mail server's IP directly. If the tool said Spamhaus but the confirmation is clean, you were looking at a public-resolver sentinel.
  2. Fix the cause before you request delisting. A compromised host or web form sending spam, an open relay, a marketing blast that drew complaints, a spam-trap hit. Delist without fixing the source and you'll just get relisted.
  3. Then delist. Each list has a removal page; most process within hours to days once the abuse has stopped. On a shared IP (a shared host or ESP), the listing may be a neighbor's fault — escalate to your provider.

The one-line version: a 127.255.255.x answer means "I won't answer a public resolver," not "you're a spammer" — and a blocklist checker that can't tell the two apart will scare you about the biggest list on the internet for no reason. A check is only as good as its ability to say "inconclusive."

The free blacklist / DNSBL checker resolves your domain's mail IPs and queries a curated set of free blocklists (SpamCop, UCEPROTECT, Spamhaus ZEN, Barracuda, Mailspike, PSBL, DroneBL, GBUdb) — and it classifies the public-resolver sentinel as inconclusive rather than a false listing, links every real listing straight to its delisting page, and tells you plainly when it couldn't get a definitive answer. No signup, one domain at a time.

A one-off check is a snapshot, though, and a listing arrives without warning — you usually find out only after mail has already started bouncing. Merlonix re-checks your domains against the major blocklists on a schedule from a stable source and alerts you the moment a new listing appears, so you can fix the cause and request delisting before your deliverability collapses. It's the same continuous-from-outside posture Merlonix takes to SPF, DKIM and DMARC and SSL and DNS — the other three ways your mail and your domain quietly break. Run the free blacklist scan to see where you stand right now, and browse the rest of the free tools while you're there.

Top comments (0)