Glossary

    SMTP Reply Codes: What Each Class Instructs

    The short answer

    An SMTP reply code is the three-digit number a receiving mail server returns to each command in an email transaction. The first digit carries the instruction: 2 and 3 mean proceed, 4 means the failure is temporary and the client should retry, and 5 means it is permanent and the client should not repeat the request.

    Key takeaways

    • The first digit is an instruction to the sending client, and every hard and soft bounce label in a sending platform is a rendering of that one digit.
    • Enhanced status codes carry the diagnosis: a subject sub-code of 1 or 2 is about the address, and a subject sub-code of 7 is about your sending policy standing.
    • A 550 and a 554 arrive for dead mailboxes and for refused senders alike, and removing the recipient makes a policy refusal worse rather than better.
    • A transient failure scattered across many receiving domains is noise; the same failure concentrated at one domain is a rate or reputation reading.

    An SMTP reply code is the three-digit number a receiving mail server returns to each command in an email transaction, and it is the machine-readable part of a delivery result. The first digit says whether the command succeeded, failed temporarily or failed permanently; the text after the number is written for a human and carries the reason.

    Every bounce report, every deferral and every block in a sending platform is a rendering of one of these numbers. Learning to read the digits is what separates a list problem from a sending problem, and those two have opposite remedies.

    What the three digits carry

    RFC 5321, the SMTP specification, defines four values for the first digit and gives each one an instruction to the sending client rather than a description of a mood.

    A 2yz is a Positive Completion reply: "The requested action has been successfully completed." A 3yz is a Positive Intermediate reply, used mid-sequence, where "The command has been accepted, but the requested action is being held in abeyance, pending receipt of further information."

    A 4yz is a Transient Negative Completion reply. The specification says "The command was not accepted, and the requested action did not occur. However, the error condition is temporary, and the action may be requested again", and it adds that the client "SHOULD try again."

    A 5yz is a Permanent Negative Completion reply: "The command was not accepted and the requested action did not occur. The SMTP client SHOULD NOT repeat the exact request (in the same sequence)."

    That pair of instructions is the entire bounce taxonomy every sending tool implements. A 4xx is queued and retried, and your platform reports it as a soft bounce. A 5xx ends the attempt, and your platform reports it as a hard bounce and flags the address.

    The second digit is a category rather than a severity. The specification assigns x0z to syntax, where "These replies refer to syntax errors", x1z to information requests, x2z to connections, where "These are replies referring to the transmission channel", and x5z to the mail system, where "These replies indicate the status of the receiver mail system". The third digit is the fine grain: "The third digit gives a finer gradation of meaning in each category specified by the second digit."

    Positive: 2yz and 3yzProceed
    • 2yz: the requested action completed
    • 3yz: accepted, waiting for more of the sequence
    • Seen during the transaction, rarely surfaced to you
    • 250 after the message body is the send you were hoping for
    • 354 is the invitation to send the message data
    Negative: 4yz and 5yzRetry, or stop
    • 4yz: temporary, the specification says try again
    • 5yz: permanent, do not repeat the exact request
    • Your platform maps 4xx to soft and 5xx to hard
    • The mapping threshold on repeated 4xx is a product decision
    • Both classes can be about the sender rather than the address
    The four first digits defined in RFC 5321, read as instructions to the sending client. The instruction is what a platform implements, and it is why the same address can be retried by one tool and abandoned by another.

    The codes a sending programme actually meets

    Most of the code space belongs to protocol conversation nobody sees. A short list accounts for nearly everything that reaches a campaign report, and the reply text in the specification is worth reading once because platforms paraphrase it inconsistently.

    On the transient side, 421 is "Service not available, closing transmission channel", which is the receiver ending the connection and is frequently a rate signal rather than a fault. 450 is "Requested mail action not taken: mailbox unavailable" and 451 is "Requested action aborted: error in processing". 452 is "Requested action not taken: insufficient system storage", which in modern practice is more often a per-connection recipient limit than a full disk.

    On the permanent side, 550 is "Requested action not taken: mailbox unavailable", which is the classic dead-address bounce and also the code most policy refusals arrive under. 551 and 553 cover routing and disallowed mailbox names, 552 is "Requested mail action aborted: exceeded storage allocation", and 554 is "Transaction failed", the general permanent refusal a gateway returns when it has decided against the message or the sender.

    Two of those deserve a warning. A 550 says nothing about whether the address exists when the receiving side declined the sender instead, and a 554 at connection time is a statement about your sending reputation rather than about anybody's mailbox. Both land in the same bucket in a dashboard as a genuinely dead address, and removing the recipient makes a policy refusal worse rather than better.

    Enhanced status codes, and why they are the better number

    The three-digit code is coarse by design, and a second standard exists precisely because of that. RFC 3463 defines enhanced mail system status codes, written as three dotted numbers such as 5.1.1, and they are the part of a bounce string worth extracting.

    The structure is stated plainly: "The first sub-code indicates whether the delivery attempt was successful. The second sub-code indicates the probable source of any delivery anomalies, and the third sub-code indicates a precise error condition."

    The first sub-code repeats the SMTP classes, with one clarification that matters for cold sending. A 4 class is a persistent transient failure, and the specification describes it as one "in which the message as sent is valid, but persistence of some temporary condition has caused abandonment or delay of attempts to send the message." A 5 class is "one which is not likely to be resolved by resending the message in the current form."

    The second sub-code is where the diagnosis lives, because it names the party responsible. X.1 is addressing status, X.2 is mailbox status, where "Mailbox status indicates that something having to do with the mailbox has caused this DSN", X.3 is the destination system, X.4 is network and routing, and X.7 is "Security or Policy Status", which is the subject code that covers filtering and sender policy.

    1. Step 1First digit

      4 means retry, 5 means stop. This is what your platform already acted on.

    2. Step 2Enhanced class and subject

      The dotted code, if present. X.1 and X.2 point at the address, X.7 points at policy.

    3. Step 3The human text

      The reason, in the receiver's own words, often naming a policy page or a listing.

    4. Step 4The pattern across the send

      Scattered across many domains, or concentrated at one. That is the real verdict.

    How to read a bounce string in the order the information gets more useful. Most reporting surfaces the first step prominently and buries the third.

    The rule of thumb worth carrying: a subject sub-code of 1 or 2 is a statement about the address, and a subject sub-code of 7 is a statement about you. A programme that separates those two before reacting will fix the right thing.

    What to do with each class in a cold programme

    Section illustration: What to do with each class in a cold programme

    Four responses cover the ground, and choosing the wrong one is how a fixable sending problem becomes a domain problem.

    A 5xx with an addressing or mailbox subject is list work. The address leaves the sending list immediately and does not come back, because repeated permanent failures are counted against you by receiving systems as a list-quality signal. Preventing it happens before the send, and the economics of that are in email list cleaning.

    A 5xx with a policy subject is sending work. Removing the recipient changes nothing, because the recipient was never the problem. The fix is on your side, in sender reputation and authentication, and sending into that provider again before it is fixed compounds the signal.

    A 4xx scattered thinly across many receiving domains is noise. Queues retry and most of it resolves without intervention. Reading a rate off the first hour after a send is reading a provisional number, and a figure taken once delivery reports have settled is the only one worth comparing to anything.

    A 4xx concentrated at one receiving domain is a rate or reputation reading. It usually means that provider is throttling you specifically, which is a different event from your own platform declining to dispatch. Which side the limit sits on is covered in email throttling, and the ceiling each provider publishes is in email sending limits by provider.

    Two structural cautions apply on top. A domain configured to accept mail for every local part returns no permanent failure at the door even for a fictional mailbox, so a clean bounce report over a catch-all domain proves less than it appears to. And some receiving systems accept the message and reject the recipient afterwards, which produces the failure minutes or hours later as a separate report.

    Where the code stops being informative

    The digits are a verdict and not a reason, and three things follow from that.

    The reply text is the only part that names the cause, and most reporting interfaces show the verdict prominently and put the text behind a click. Diagnosing anything without reading the text is guessing between three unrelated causes that share a code, which is the problem bounce back email works through case by case.

    The soft and hard labels in your dashboard are your tool's mapping rather than the receiver's words, and platforms differ on how many transient refusals it takes before an address is reclassified. That is why the same address can be a soft bounce in one tool and a hard bounce in another, and why a rate is partly a property of your tooling. The comparison is drawn out in hard bounce versus soft bounce.

    And a relay in the path adds a hop that can generate its own codes under its own rules, which is a different failure surface from the receiving domain's. What that hop does is in SMTP relay, what the server underneath it is doing is in SMTP server, and the connection settings that decide whether the conversation happens at all are in SMTP ports.

    Hard bounce and soft bounce cover the two classes these codes produce and what each one obliges you to do. Email deliverability covers what the codes are evidence about, sender reputation covers the side a policy refusal is talking about, mailbox provider covers who is making the decision, and catch-all domain covers the configuration that suppresses the signal entirely.

    On the mechanics, SMTP relay covers the hop, SMTP server covers what breaks first at volume, SMTP ports covers the connection, bounce back email covers diagnosing a single failure, and email list cleaning covers the pre-send work that prevents most permanent failures.

    If the codes are clean and the replies still are not there, the constraint is the list and the premise rather than the plumbing. See what a first campaign produces against your market.

    Specification text above is verbatim from RFC 5321 and RFC 3463, fetched from the RFC Editor on 2 September 2026.

    Questions

    Frequently asked questions.

    Frequently asked questions
    What is an SMTP reply code?
    The three-digit number a receiving mail server returns to each command in an email transaction. The first digit tells the sending client what to do next, the second digit gives a category such as syntax, connection or mail system, and the third digit is a finer gradation. The text printed after the number is written for a person and carries the actual reason.
    What is the difference between a 4xx and a 5xx SMTP code?
    A 4xx is a transient negative reply: the specification says the condition is temporary and the client should try again, so your platform queues the message and retries. A 5xx is a permanent negative reply and instructs the client not to repeat the request, so the attempt ends and the address is usually flagged. Platforms map the first to soft and the second to hard.
    What are enhanced SMTP status codes?
    A second, finer standard written as three dotted numbers such as 5.1.1. The first sub-code repeats the success, transient or permanent class. The second names the probable source, including addressing, mailbox, destination system, network and security or policy. The third names a precise condition. Extracting the dotted code is more useful than reading the three-digit reply alone.
    Does a 550 always mean the email address is invalid?
    No. A 550 is the classic dead-mailbox bounce and it is also the code many receiving systems return when they have declined the sender rather than the recipient. Both land in the same bucket in a campaign report. Read the enhanced status code and the reply text, and check whether the failures are scattered across domains or concentrated at one.