Reason codes
reason_codes is why. It is a closed, stable vocabulary: codes are added to
it, but never repurposed and never removed without a version change, so a branch
you write today keeps meaning what it meant.
It exists so that a destination’s reply text never crosses this boundary. That text leaks remote infrastructure detail, can carry untrusted control characters or personal data, and is reworded whenever a provider feels like it. You get a code instead, and the code is the contract.
What each code is evidence about
Section titled “What each code is evidence about”The column that matters most is the last one. Only codes bearing on this mailbox say anything about the address you asked about:
- this mailbox — about the recipient.
- the domain — about the domain, and therefore about every address at it.
- the destination’s policy — about what the destination was willing to do in
this conversation. Frequently about us: a
5.7.xis a decision about the sender. - this service — a limit we imposed or a failure we had. No evidence about anything else.
The vocabulary
Section titled “The vocabulary”Parsing
| Code | Meaning | Evidence about |
|---|---|---|
INVALID_SYNTAX | The address could not be parsed as a mailbox at all. | this mailbox |
INVALID_LOCAL_PART | The part before the @ is not a valid local part. | this mailbox |
INVALID_DOMAIN | The part after the @ is not a valid domain name. | the domain |
ADDRESS_TOO_LONG | The address is longer than SMTP permits, so nothing could deliver to it. | this mailbox |
DOMAIN_LITERAL_NOT_ALLOWED | The domain is an address literal such as user@[192.0.2.1]. This service does not verify those. | the domain |
SMTPUTF8_REQUIRED | The local part is not ASCII, so delivery requires a destination that offers SMTPUTF8. | this mailbox |
DNS and mail routing
| Code | Meaning | Evidence about |
|---|---|---|
DNS_NXDOMAIN | The domain does not exist. Nothing can be delivered to any address at it. | the domain |
DNS_NODATA | The domain exists but publishes none of the records mail delivery needs. | the domain |
DNS_TIMEOUT | Our resolver did not get an answer in time. This says nothing about the domain. | this service |
DNS_SERVFAIL | The domain's own nameservers failed to answer the query. | the domain |
DNS_DNSSEC_FAILURE | The domain's DNSSEC signatures did not validate, so its records cannot be trusted. | the domain |
NULL_MX | The domain publishes MX 0 "." — a formal declaration that it accepts no mail at all (RFC 7505). | the domain |
IMPLICIT_MX | The domain publishes no MX record, so mail falls back to its A/AAAA address. Informational, not a fault. | the domain |
MX_FOUND | Usable MX records were found. Informational — it is the ordinary case. | the domain |
MX_UNRESOLVABLE | The MX hostnames the domain publishes do not resolve to any address. | the domain |
MX_TARGET_BLOCKED | Every MX target resolves into address space this service will not dial — private or otherwise reserved. | the domain |
DOMAIN_MAIL_ROUTE_MISCONFIGURED | The domain's mail routing contradicts itself and no destination can be chosen from it. | the domain |
SMTP transport
| Code | Meaning | Evidence about |
|---|---|---|
SMTP_QUEUED | A probe was queued rather than answered inline. The verification is pending; poll for the result. | this service |
SMTP_QUEUE_EXPIRED | The queued probe passed its deadline before a worker reached it, and was abandoned. | this service |
SMTP_CONNECT_TIMEOUT | The destination did not complete a connection within the time allowed. | the destination's policy |
SMTP_CONNECT_REFUSED | The destination refused the connection outright. | the destination's policy |
SMTP_BANNER_INVALID | The destination's greeting was not a valid SMTP banner. | the destination's policy |
SMTP_PROTOCOL_ERROR | The destination broke the protocol part-way through the session. | the destination's policy |
SMTP_REPLY_TOO_LARGE | A reply exceeded the size this service will read, and the session was abandoned. | the destination's policy |
SMTP_STARTTLS_FAILED | STARTTLS was offered and the handshake failed, so the session did not continue. | the destination's policy |
SMTP_TLS_CERTIFICATE_FAILED | The destination's certificate did not validate. | the destination's policy |
SMTPUTF8_NOT_SUPPORTED | The address needs SMTPUTF8 and the destination does not offer it, so it could not be asked about. | the domain |
SMTP_SENDER_REJECTED | The destination refused our envelope sender. It never heard the recipient. | the destination's policy |
SMTP_POLICY_REJECTED | The destination refused the session on policy grounds. A 5.7.x is a decision about us, not a statement about the mailbox. | the destination's policy |
SMTP_EGRESS_REPUTATION_REJECTED | The refusal named our outbound address's standing. It is about this service's reputation and nothing else.`SMTP_EGRESS_REPUTATION_REJECTED` marks a refusal aimed at our outbound identity. It says nothing about the recipient and everything about our own standing, which is why it is tracked apart from a generic sender refusal. | this service |
SMTP_PROVIDER_THROTTLED | The destination asked us to slow down. | the destination's policy |
SMTP_GREYLISTED | The destination asked us to come back later, which is what greylisting is. A retry is scheduled automatically. | the destination's policy |
SMTP_TEMPORARY_FAILURE | The destination returned a 4xx. A retry is scheduled automatically. | the destination's policy |
Recipient outcomes
| Code | Meaning | Evidence about |
|---|---|---|
SMTP_RCPT_ACCEPTED | The destination accepted this recipient in a live transaction. Evidence, not proof — see the catch-all page. | this mailbox |
SMTP_MAILBOX_NOT_FOUND | The destination said there is no such mailbox. | this mailbox |
SMTP_MAILBOX_DISABLED | The mailbox exists and is not accepting mail — disabled, suspended or full. | this mailbox |
SMTP_MAILBOX_STATUS_ERROR | The destination reported a problem with the mailbox without classifying it further. | this mailbox |
SMTP_FORWARDING_INDICATED | The destination indicated the recipient is forwarded somewhere else. | this mailbox |
SMTP_RECIPIENT_REJECTED_AMBIGUOUS | The recipient was refused with a reply that does not separate "no such mailbox" from "not from you". | the destination's policy |
Risk and profile signals
| Code | Meaning | Evidence about |
|---|---|---|
DISPOSABLE_DOMAIN | The domain belongs to a throwaway-mailbox provider. The address may well accept mail; whether you want it is a business decision. | the domain |
ROLE_ACCOUNT | The local part is a role — info, support, admin — rather than a person. Often deliverable and rarely what a signup form wants. | this mailbox |
ACCEPT_ALL_DOMAIN | The domain accepts every recipient, so an acceptance establishes nothing about this one in particular. | the domain |
ACCEPT_ALL_UNKNOWN | Whether the domain accepts everything could not be established, so an acceptance cannot be weighed. | the domain |
LIKELY_DOMAIN_TYPO | The domain is one small edit from a large provider. The suggestion field carries the likely intent. | the domain |
SMTP_PROBE_SKIPPED_PROVIDER_POLICY | No probe was sent: this provider accepts every recipient at its edge, so a session would have established nothing. | this service |
SMTP_PROBE_NOT_REQUESTED | No probe was sent because the request asked for the domain depth.`SMTP_PROBE_NOT_REQUESTED` reports a probe this service did not send because the caller did not ask for one. Distinct from the code above, and the distinction is the caller's to read: one says we declined to ask a destination that would not have answered, the other says they bought the cheaper depth. Collapsing them would leave somebody unable to tell a decision of ours from a decision of theirs. | this service |
PROVIDER_CIRCUIT_OPEN | Probing to this destination is suspended after repeated failures against it. | this service |
Degraded-dependency signals
| Code | Meaning | Evidence about |
|---|---|---|
SMTP_QUEUE_UNAVAILABLE | The probe could not be queued. Ours to fix, and no evidence about the address. | this service |
SMTP_SCHEDULER_UNAVAILABLE | The probe could not be scheduled. Ours to fix, and no evidence about the address. | this service |
SMTP_EGRESS_UNAVAILABLE | The probe never left this service. No destination was contacted.`SMTP_EGRESS_UNAVAILABLE` reports a probe that never left this host: an egress identity that cannot be bound, a destination the filter refuses, a route the resolver never validated. It belongs in this group rather than among the transport failures because it says nothing whatsoever about the destination. Recorded as one of those — which is what happened while every non-timeout dial error mapped to SMTP_CONNECT_REFUSED — it feeds the breaker that suspends a destination, and a local misconfiguration acquires the appearance of a provider outage. | this service |
SMTP_PACING_REFUSED | We declined to send the probe because this destination's allowance for the period was spent. The destination said nothing.`SMTP_PACING_REFUSED` reports a probe this service declined to send because the destination's allowance was spent. Ours, like the two above, and that is the whole reason it is a code of its own rather than SMTP_PROVIDER_THROTTLED. The destination said nothing; we decided on its behalf. Recorded as the destination throttling us it would feed the breaker that suspends destinations, and a busy hour would suspend the very providers behaving best. | this service |
Reading the list
Section titled “Reading the list”A result carries several codes and they are not ranked. MX_FOUND beside
SMTP_RCPT_ACCEPTED is the ordinary shape of a good answer; ACCEPT_ALL_DOMAIN
beside SMTP_RCPT_ACCEPTED is the shape of an acceptance that
establishes nothing. Read the set, not the first entry.
Duplicates are collapsed. Repeated evidence for the same conclusion appears once.
Some codes are informational. MX_FOUND and IMPLICIT_MX describe ordinary
mail routing rather than a fault.
51 codes · vocabulary 58ec1bc7ba0b — a
digest of the values themselves, taken from the service. It moves when the
vocabulary does and not when this page is edited.