Start with two facts: which list, which IP

Most of the time spent on blacklist problems goes on checking the wrong thing. Before anything else, pin down which list is involved and which IP address it listed.

Which list. The bounce usually says. Receivers that reject on a DNS blocklist (DNSBL, also called RBL) normally name it in the SMTP response, for example “blocked using zen.spamhaus.org” or a URL pointing at the list’s lookup page. Copy the full bounce text; it’s the most precise evidence you have.

Which IP. The IP that matters is the one that connected to the receiver, not the one your domain’s A or MX record points to. Send a message to a Gmail address, open “Show original” and find the first Received: header added by Google:

Received: from mail.example.com (mail.example.com. [203.0.113.10])
        by mx.google.com with ESMTPS id ...

That bracketed address is your sending IP. On the server itself, curl -4 -s https://ifconfig.me shows the public address its outbound traffic leaves from, which differs from the server’s own address when it sits behind NAT.

This matters because of three common mix-ups:

  • Inbound vs outbound. Your MX servers receive mail; they don’t necessarily send it. If you use one host for both, they’re the same. Otherwise a check of your MX IPs says nothing about your outbound reputation.
  • Shared providers. If you send through Google Workspace, Microsoft 365, or a sending service such as SES or SendGrid, your mail leaves from the provider’s IPs. You can’t delist those, and you aren’t expected to. Problems there are about your domain’s authentication and reputation.
  • Office NAT. A whole office often shares one public IP. If a single infected laptop sends spam or talks to a botnet, the shared IP gets listed, and the mail server behind it gets blocked even though it did nothing wrong.

Checking a list yourself

A DNSBL is just a DNS zone. To ask whether 203.0.113.10 is listed, reverse the octets and look the name up under the list’s zone:

$ dig +short 10.113.0.203.bl.spamcop.net
$ dig +short 10.113.0.203.b.barracudacentral.org
127.0.0.2

No answer (NXDOMAIN) means not listed. An answer in 127.0.0.0/8 means listed, and some lists use the last octet to say why. A TXT lookup on the same name often returns a short reason or a URL:

dig +short TXT 10.113.0.203.b.barracudacentral.org

Every DNSBL that follows RFC 5782 lists 127.0.0.2 as a permanent test entry, so dig +short 2.0.0.127.bl.spamcop.net should always answer. If it doesn’t, your query isn’t reaching the list, and a blank answer for your real IP means nothing.

Spamhaus is the exception you need to know about. Spamhaus refuses queries that arrive through large public resolvers such as 8.8.8.8 or 1.1.1.1, and answers them with a code in 127.255.255.0/24 instead of a real result. 127.255.255.254 means “query came through a public resolver”, not “listed”. A checker that doesn’t handle this reports every IP as listed on Spamhaus. Use Spamhaus’s own IP and Domain Reputation Checker at check.spamhaus.org, or query from a server with its own recursive resolver. When the query does get through, the main return codes for zen.spamhaus.org are:

AnswerListMeaning
127.0.0.2SBLSpam source or spam operation identified by Spamhaus staff
127.0.0.3CSSLow-reputation sending detected automatically
127.0.0.4XBLCompromised or infected host (malware, proxy, botnet)
127.0.0.10, 127.0.0.11PBLAddress range not meant to send mail directly to the internet

The email check does this for you. Enter an IP address and it queries SpamCop, Barracuda and PSBL and shows the IP’s reverse DNS. Spamhaus shows “Could not check” for the reason above, so check Spamhaus separately. Enter a domain instead and it checks the IPs of the domain’s MX servers, which are your inbound servers; use the IP form for your outbound address. IP check shows the public IP and network of whatever device you open it from.

What the listing tells you about the cause

Different lists list for different reasons, and the reason points to the fix.

  • XBL (Spamhaus): something on that IP is infected or is being used as a proxy. On a dedicated mail server that’s a compromised server. On an office or home connection it’s usually a PC, phone, camera or router behind the NAT, not the mail server.
  • PBL (Spamhaus): not a penalty. The ISP has marked the range as dynamic or end-user space that shouldn’t deliver mail directly. If you’re running a mail server on a residential or dynamic connection, send through your ISP’s or provider’s relay (a smarthost) instead. If it’s a static IP you legitimately use for mail, Spamhaus’s lookup page explains how to request removal from the PBL.
  • SBL and CSS (Spamhaus), SpamCop, Barracuda, PSBL: these respond to mail that actually reached spam traps or was reported as spam. Something sent it. Your job is to find out what.
  • Range listings: some lists, UCEPROTECT’s levels 2 and 3 being the best-known, list whole provider ranges or networks because of what neighbouring addresses did. Nothing on your server can fix that; the listing is about your hosting provider.
  • Domain lists (Spamhaus DBL, SURBL, URIBL) list domains that appear in message bodies, not IPs. If one of these names your domain or a link in your mail, delisting your IP won’t help; the problem is the domain or URL, sometimes a link shortener or a compromised page on your site.

SORBS, which appears in a lot of old checklists, shut down in 2024. Its zone no longer answers, so any tool still querying it reports every IP as clean.

The big mailbox providers are a separate case. Gmail and Microsoft run their own reputation systems instead of relying on public lists alone. Their rejections carry their own codes, and Microsoft’s rejection text points to its own delisting process. A clean result on every public DNSBL doesn’t mean Gmail or Outlook trust you.

Find what’s sending before you ask for removal

Requesting removal before fixing the source is the most common mistake, and it backfires: the source is still sending, so the IP gets relisted. These are the usual causes.

A compromised mailbox password

Spammers log in with stolen credentials and send through your server using authenticated SMTP. Everything looks legitimate except the volume. On Postfix, count authenticated logins per user:

grep -oE 'sasl_username=[^ ,]+' /var/log/mail.log | sort | uniq -c | sort -rn | head

One account with thousands of logins, or logins from countries where you have no staff, is your answer. Reset the password, end its sessions, turn on MFA where the platform supports it, and look at its sent folder to see what went out.

A script or web form

A contact form with no rate limit or CAPTCHA, a vulnerable plugin, or an uploaded PHP shell can send through the local mail system without any login. Check the queue first:

postqueue -p | tail -n 1        # e.g. "-- 2048 Kbytes in 3150 Requests."
postqueue -p | head -n 40       # who are they from, and to whom?

A queue in the thousands on a server that normally holds a handful is a strong sign. Look at the sender addresses and a couple of message bodies (postcat -q <QUEUE_ID>), then find the script in the web server’s access log around the same times.

An infected host

For XBL-type listings, look for connections to remote port 25 from anything that isn’t your mail server:

ss -tnp state established '( dport = :25 )'

On a mail server, only the MTA process should appear. On an office network, check the firewall for internal hosts connecting outbound on port 25; blocking outbound 25 for everything except the mail server is the long-term fix.

An open relay

Test from a machine outside your network, without logging in, sending from a domain that isn’t yours to a domain that isn’t yours:

swaks --server mail.example.com --from test@example.net --to someone@example.org

The right answer is a refusal such as 554 5.7.1 <someone@example.org>: Relay access denied. If the message is accepted, your server relays for anyone, and fixing that comes before everything else. On Postfix, postconf smtpd_relay_restrictions should include reject_unauth_destination.

Backscatter

If your server accepts mail for addresses that don’t exist and then sends a bounce, the bounces go to the forged sender addresses on spam, which are real people who never wrote to you. That’s backscatter, and some lists list for it. Reject unknown recipients during the SMTP conversation instead of accepting and bouncing later.

Your own bulk mail

If none of the above, look at what you sent deliberately: a purchased or very old list, a newsletter sent to people who never opted in, a sudden jump in volume from a new IP. Spam traps are old abandoned addresses and addresses that were never handed out, and they end up on lists that weren’t collected with consent. The fix is the list, not the server.

Requesting removal

Once the source is gone and you’ve watched the server for a day or two to confirm it, go to each list that has you. Do it one list at a time, and be specific about what you found and fixed.

  • Spamhaus: use the lookup at check.spamhaus.org. It explains each listing and, where removal is self-service, offers it there. For XBL and CSS, removal only sticks if the source is really fixed.
  • SpamCop: listings expire on their own once reports about the IP stop. SpamCop says this happens within about a day. There’s nothing to request; fix the source and wait.
  • Barracuda: Barracuda Central has a removal request form. Requests are reviewed, so include what you fixed.
  • PSBL: its website lets you look up and remove an IP yourself.
  • Microsoft, Gmail and other mailbox providers: follow the link or code in their rejection message. These aren’t DNSBLs, and the process is theirs.

Avoid services that offer to delist you for a fee from lists that don’t charge. And if you’re on a range listing, the request has to go to your hosting provider, not the list.

Keeping it off

  • Rate-limit outbound mail and alert on sudden spikes. Postfix’s built-in smtpd_client_message_rate_limit works per client IP; per-user limits need a policy service.
  • Block outbound port 25 at the firewall for every host except the mail server.
  • Put rate limits and a CAPTCHA on every web form that sends mail.
  • Give your sending IP a matching reverse DNS name and keep SPF, DKIM and DMARC passing. They won’t stop a listing, but missing basics make every receiver less forgiving. See reverse DNS / PTR setup and the email deliverability guide.
  • Re-check your sending IP with the email check after any incident, and Spamhaus on its own site.

Check your own domain now

Free, no sign-up. Runs the exact check this guide describes and shows what to fix.