Bounce codes: reading the rejection your receiver actually sent
Your email is being rejected because the receiving mail server refused it, and it wrote the reason into the bounce before it closed the connection. Every rejection has a three digit code, a longer dotted code, and a sentence of text. Most campaign platforms hide that sentence behind a label like “hard bounce”, which is why nobody on your side can tell you what went wrong. This page takes the code you have and sends you to the page that fixes it.
Find the three parts of the rejection
Open the bounce itself: the message with a subject like “Delivery Status Notification (Failure)” or “Undelivered Mail Returned to Sender”, or the SMTP response column in your platform’s bounce export. Somewhere in it is a line shaped like this one:
550-5.7.26 This mail has been blocked because the sender is unauthenticated.
The first number is the reply code from the SMTP conversation. A code beginning with 4 means “not now, try again later” and a code beginning with 5 means “no, and do not retry”. The second number is the enhanced status code, and its middle digit says what kind of problem the receiver is reporting: 1 is the address, 2 is the mailbox, 4 is routing, 7 is policy.
Everything after that is the receiver’s own wording, and it is the part worth reading twice, because one code such as 5.7.1 covers a dozen different refusals and only the text separates them. Find your line below by its dotted code first, then by a phrase in the text.
It begins with 4: a deferral, so look at volume before anything else
A 4xx response means the receiver has accepted nothing yet and expects your server to try again. Your platform retries on its own for a day or two, so a single 421 in the log is noise. A wall of them during a send says something about how the receiver sees the source, and the text tells you which source it means.
421-4.7.0 [203.0.113.5] Our system has detected an unusual rate of unsolicited mail originating from your IP address.
421-4.7.28 Gmail has detected an unusual rate of unsolicited mail originating from your DKIM domain.
451 4.7.650 The mail server [203.0.113.5] has been temporarily rate limited due to IP reputation.
421 4.7.0 [TSS04] Messages from 203.0.113.5 temporarily deferred due to unexpected volume or user complaints
4.7.0 and 4.7.650 name the IP address, which belongs to whoever runs the sending server. On a shared platform that address is shared with every other customer on it, so the deferral may have nothing to do with your list.
4.7.28 names your DKIM domain, and that one is yours: the receiver has decided that the volume signed under your name climbed faster than its model of you allows. A new domain on its first large send gets this almost every time, so spread the send over several days and the deferrals will clear.
If the deferrals carry on for more than a day the receiver has made up its mind, and the text in the 5.7.1 branch below will match yours.
5.1.x and 5.2.x: the address was the problem
These codes describe the recipient, and nothing you change on your own domain will alter them.
550 5.1.1 The email account that you tried to reach does not exist.
550 5.1.10 RESOLVER.ADR.RecipientNotFound; Recipient not found by SMTP address lookup
552-5.2.2 The email account that you tried to reach is over quota.
5.1.1 and 5.1.10 mean the mailbox has gone. Suppress the address and never send to it again, because a list that keeps hitting unknown users looks, to the receiver, like a list that was bought or scraped. 5.2.2 is a full mailbox and clears itself when the owner deletes something; your platform retries and then suppresses.
If most of your bounces sit in this branch you have a list problem, and the rest of this page will not help until the list is cleaned.
5.7.26, 5.7.509 and 5.7.9: the receiver checked your domain and it did not pass
Campaign mail lands here most often after a platform migration, and the text names the check the receiver ran.
550-5.7.26 This mail has been blocked because the sender is unauthenticated. Gmail requires all senders to authenticate with either SPF or DKIM.
550-5.7.26 Unauthenticated email from example.com is not accepted due to domain's DMARC policy. Please contact the administrator of example.com domain if this was a legitimate mail.
550-5.7.26 The MAIL FROM domain [example.com] has an SPF record with a hard fail policy (-all) but it fails to pass SPF checks with the ip: [203.0.113.5].
550 5.7.509 Access denied, sending domain example.com does not pass DMARC verification and has a DMARC policy of reject.
550 5.7.515 Access denied, sending domain example.com does not meet the required authentication level.
554 5.7.9 Message not accepted for policy reasons.
Your campaign platform sends from its own servers, with your domain in the From line the reader sees. For a receiver to accept that arrangement, one of two things has to be true: the platform’s servers are listed in your domain’s SPF record, or the message carries a DKIM signature made with a key published under your domain.
The receiver then checks alignment, meaning the domain that passed has to match the domain in From. When neither check passes in alignment the message is unauthenticated, and if your DMARC record says p=reject the receiver bounced the campaign because your record told it to.
The first 5.7.26 line means neither SPF nor DKIM passed at all. Your platform’s setup page gave you a CNAME or TXT record to publish for signing when you signed up; if nobody got round to publishing it, that’s the record the receiver couldn’t find. The DKIM piece walks through the signature and its selector, then shows you what “did not pass” looks like in a header.
The hard fail line means your SPF record ends in -all and the platform’s server is missing from it. You add the include the platform gives you, count the DNS lookups so you stay under ten, and republish. The SPF piece reads the record mechanism by mechanism, including the ending.
5.7.509, 5.7.515 and 5.7.9 are the DMARC branch. The receiver looked up _dmarc.example.com, found a policy, and did what the policy said. The DMARC piece explains what each p= value instructs a receiver to do and how to move from none to reject without bouncing your own invoices.
The bulk sender rules that Gmail and Yahoo brought in during 2024 test this branch and nothing else: a published DMARC record, SPF or DKIM passing, and the From domain aligned. Of the 78,444,857 DMARC records the September 2026 census found in the live DNS, 36,602,897 have an enforcing policy (p=quarantine or p=reject) and 41,798,631 say p=none, which tells a receiver to report and deliver.
A domain in the p=none group passes the rules. A domain with no record at all fails them before the message body is read, and so does a domain whose record is there while the signing key never got published. The scan below reads your domain the way the receiver did, prints the SPF record, looks for a DKIM key under the common selectors, and shows you the DMARC policy that would bounce your next send.
5.7.25: the sending server has no name
550-5.7.25 [203.0.113.5] The IP address sending this message does not have a PTR record setup, or the corresponding forward DNS entry does not point to the sending IP.
A PTR record is the reverse of an A record. It turns an IP address back into a hostname, and receivers expect the hostname to resolve forward to the same address. Every campaign platform sets this on its own servers before it takes a single customer, so a 5.7.25 on campaign mail almost always means the message left from somewhere else, an office mail server say, or a CRM plugin that sends its own notifications.
Open the bounced copy and read the Received: headers from the bottom up; the first hop names the machine. Whoever owns that IP address publishes the PTR, which is usually the hosting company rather than you. Ask them for a PTR that matches the hostname in the server’s HELO greeting, or move that traffic onto the platform whose servers already have one.
5.7.1 with a list name or a tag in it: the address or the content
Two different refusals share this code, and only the text tells you which one you got.
550 5.7.1 Service unavailable, Client host [203.0.113.5] blocked using Spamhaus.
553 5.7.1 [BL21] Connections will not be accepted from 203.0.113.5, because the ip is in Spamhaus's list
550 5.7.1 Unfortunately, messages from [203.0.113.5] weren't sent. Please contact your Internet service provider since part of their network is on our block list (S3140).
550 5.7.501 Service unavailable. Spam abuse detected from IP range.
These four describe the sending IP address, and the receiver has refused the connection before it read a word of your message. If the address belongs to your platform, open a ticket and stop the send until they answer, because every further attempt from that address is logged against it. If it belongs to a server you run, the listing site names the reason and the delisting form. Fix whatever caused the listing before you ask (an open relay, say, or a compromised account), or the listing returns within the week.
550-5.7.1 [203.0.113.5] Our system has detected that this message is likely unsolicited mail. To reduce the amount of spam sent to Gmail, this message has been blocked.
550-5.7.1 Messages missing a valid address in From: header, or having no From: header, are not accepted.
550-5.7.1 Messages missing a valid messageId header are not accepted.
These three are about the message. The last two are template faults and a developer fixes them in an afternoon: a From address that is a real mailbox on your domain, and a Message-ID: header on every message. The first is the receiver’s classifier weighing your content against the complaint history of your domain, and a big part of that history comes down to how easily a reader can leave. The large receivers expect bulk mail to have both of these headers, and the second one is the one most templates forget:
List-Unsubscribe: <mailto:[email protected]?subject=unsubscribe>, <https://example.com/u/7f3a9c>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
With both present the receiver shows its own unsubscribe button next to your From name, and a reader who is done with you presses that instead of the report-spam button beside it, so fewer complaints get logged against your domain and the classifier’s view of you improves as they drop.
Before the next send
Add a seed address at each large receiver to every campaign and open the raw source of the copy that arrives. The line you want is Authentication-Results:, and a healthy one reads like this:
Authentication-Results: mx.example; spf=pass smtp.mailfrom=bounce.platform.example; dkim=pass header.d=example.com header.s=k1; dmarc=pass header.from=example.com
header.d is the domain that signed the message. If it shows the platform’s domain instead of yours, the signature passes on a borrowed identity and does nothing for your DMARC alignment; go back to the setup page and publish the custom domain key. dmarc=pass with header.from equal to your own domain is the state every branch above was trying to reach, and the smtp.mailfrom domain can be the platform’s without harm, because the alignment that matters here is DKIM’s.
Then run the scan on your own domain the week before a campaign. The three records change whenever someone adds a tool or a colleague tidies the DNS, and the receiver will find the change before you do. The scan takes about a minute, which is a lot cheaper than learning about the change from a 550 after the send has gone out.
Figures as of 5 September 2026, from the September 2026 edition of the defaults.exposed census. Census numbers move every month; the current values are on the census data page.