When a server refuses mail, it replies with a three-digit code and, usually, a more precise “enhanced” code such as 5.1.1. The first digit is the one that matters most.
The first digit
| Starts with | Meaning | Treat it as |
|---|---|---|
| 2 | Accepted | Delivered to the server |
| 4 | Temporary failure | A soft bounce, the server may accept it later |
| 5 | Permanent failure | A hard bounce, do not retry |
Codes you will see often
| Code | Usually means |
|---|---|
421 |
The server is busy or closing the connection. Try again later. |
450 / 452 |
The mailbox is unavailable or full for now. |
550 |
The request was refused. The text says why. |
552 |
The mailbox is over its storage limit. |
553 |
The address is not allowed or is badly formed. |
554 |
The transaction failed, often for policy reasons. |
Enhanced status codes
The three-part code, written class.subject.detail, is more specific.
| Code | Usually means |
|---|---|
5.1.1 |
The destination mailbox does not exist. |
4.2.2 / 5.2.2 |
The mailbox is full. |
5.7.1 |
Refused for policy reasons, such as a blocklist or a failed authentication check. |
4.4.7 |
The message expired in the queue before it could be delivered. |
Reading a bounce
Start with the first digit to decide whether you are looking at a list problem or a moment-in-time problem. Then read the text, because mailbox providers write their own explanations, and a 550 5.7.1 with a link to a policy page is a different problem from a 550 5.1.1 for an unknown user. The first points at your sender reputation or authentication, the second at your list.
Common questions
What does a 550 error mean?
A 550 means the receiving server refused the message permanently. The text after the code tells you why, for example that the mailbox does not exist or that your message was rejected as spam.
Where do I find the code for a bounce in SES?
In the bounce notification, in the diagnostic code field of each bounced recipient. It is the text the receiving server returned.