Email Spam Tester Run a test · API

How the test works

Send one message to a disposable address and 39 checks run against it. This page is all of them: what each one looks at, what it costs your score when it fails, and the section of the standard it comes from.

Nothing here is our opinion dressed as a rule. Where a check enforces something a standard says, the sentence from that standard is quoted underneath it. Where it enforces something Google or Yahoo requires instead, their page is linked. Where it is our own judgement, it says so.

Authentication

Whether the receiving server can prove the message came from where it says. This is the half of deliverability that is pure DNS, and the half Gmail and Yahoo made mandatory for bulk senders in 2024.

ARC chain auth.arc

ARC preserves the authentication result across a forwarder. Without it, a mailing list that appends a footer breaks your DKIM signature and the forwarded copy fails DMARC at the far end.

If it fails: Nothing to do as a sender. This matters if you run a list or a forwarder, and it explains why some of your mail fails DMARC after somebody forwards it.

Costs up to 2 points of 100 on our score.

RFC 7960 §1 — Introduction

DMARC with restrictive policies causes problems for many Mailing Lists.

RFC 8617 §2.1 — Evidence

In ARC's situation, the "evidence" is a message's authentication assessment at any point along the delivery path between origination and final delivery.

Google — Requirements for bulk senders (5,000+/day)

DKIM signature auth.dkim

DKIM signs parts of the message with a private key and publishes the public key in DNS. We verify every signature the message carries and report the signing domain, the selector and the key length.

If it fails: Turn on DKIM at your sending platform and publish the key it gives you. Use 2048 bits (1024 still verifies, but it is on its way out).

Costs up to 18 points of 100 on our score and up to 1 of 10 on the classic score.

RFC 6376 §3.5 — The DKIM-Signature Header Field

The signature of the email is stored in the DKIM-Signature header field.

RFC 6376 §6.1 — Extract Signatures from the Message

Verifiers MUST NOT attribute ultimate meaning to the order of multiple DKIM-Signature header fields.

Google — Turn on DKIM for your domain

Google — Requirements for bulk senders (5,000+/day)

DKIM alignment auth.dkim_alignment

A valid signature is not enough for DMARC. The signing domain has to match the domain in the From header, exactly or by organisational domain depending on the policy you published.

If it fails: Sign with your own domain rather than your platform's. Most platforms support this and call it a custom or authenticated sending domain.

Costs up to 10 points of 100 on our score and up to 1 of 10 on the classic score.

RFC 7489 §3.1.1 — DKIM-Authenticated Identifiers

DMARC permits Identifier Alignment, based on the result of a DKIM authentication, to be strict or relaxed.

Google — Add a DMARC record

Google — Requirements for bulk senders (5,000+/day)

DMARC result auth.dmarc

DMARC ties SPF and DKIM to the domain your reader sees and tells receivers what to do when neither aligns. We report the published policy and whether this message satisfied it.

If it fails: Publish a DMARC record. Start at p=none, read the reports for a few weeks, then move to quarantine once you know what else sends as you.

Costs up to 14 points of 100 on our score.

RFC 7489 §6.6.2 — Determine Handling Policy

DMARC evaluation can only yield a "pass" result after one of the underlying authentication mechanisms passes for an aligned identifier.

RFC 7489 §6.3 — General Record Format

DMARC records follow the extensible "tag-value" syntax for DNS-based key records defined in DKIM [DKIM].

Google — Requirements for bulk senders (5,000+/day)

Yahoo — Sender requirements and recommendations

Sender ID auth.sender_id

The same check as SPF, run against the domain in the From header rather than the envelope. It answers a different question: whether the domain your reader sees authorises the server that sent the message. A message can pass SPF on its envelope while the visible domain vouches for nobody.

If it fails: Publish SPF for the domain in your From header, not only for the bounce domain your platform gave you.

Costs up to 5 points of 100 on our score and up to 0.5 of 10 on the classic score.

RFC 4406 §4 — Record Selection

After the above steps, there should be one record remaining and evaluation can proceed.

SPF auth.spf

SPF is a DNS record listing which servers may send for your domain. The receiving server takes the address in the envelope, looks up that domain's record and checks whether the connecting IP is in it. We report the result and the number of DNS lookups the record needed, because evaluation stops at ten and anything past that is a permanent error rather than a pass.

If it fails: Publish a record that names your sending platform and nothing else. If yours is close to the ten-lookup limit, flatten the includes you do not use (a record that passes today starts failing the day a provider adds an include of its own).

Costs up to 18 points of 100 on our score and up to 1 of 10 on the classic score.

RFC 7208 §4.6.4 — DNS Lookup Limits

SPF implementations MUST limit the total number of those terms to 10 during SPF evaluation, to avoid unreasonable load on the DNS. If this limit is exceeded, the implementation MUST return "permerror".

RFC 7208 §2.6 — Results of Evaluation

Section 4 defines check_host(), a model function definition that uses the inputs defined above and the sender's policy published in the DNS to reach a conclusion about client authorization.

Google — Define an SPF record

Google — Requirements for bulk senders (5,000+/day)

SPF alignment auth.spf_alignment

Whether the bounce address matches the From address a reader sees. SPF authorises the envelope, and DMARC only counts that authorisation when the two align.

If it fails: Ask your sending platform for a bounce subdomain of your own domain. If your DKIM is already aligned this is not urgent, but it leaves you without a fallback when DKIM breaks in transit.

Costs up to 5 points of 100 on our score and up to 0.5 of 10 on the classic score.

RFC 7489 §3.1.2 — SPF-Authenticated Identifiers

In relaxed mode, the [SPF]-authenticated domain and RFC5322.From domain must have the same Organizational Domain. In strict mode, only an exact DNS domain match is considered to produce Identifier Alignment.

RFC 7489 §6.6.2 — Determine Handling Policy

If one or more of the Authenticated Identifiers align with the RFC5322.From domain, the message is considered to pass the DMARC mechanism check.

Google — Add a DMARC record

Google — Requirements for bulk senders (5,000+/day)

Infrastructure and reputation

The machine and the address the message was sent from, and what the rest of the internet already thinks of them.

Sending hostname resolves infra.a_record

Whether the hostname announced at HELO has an address record at all.

If it fails: Publish an A record for the name your server announces.

Costs up to 5 points of 100 on our score and up to 3 of 10 on the classic score.

RFC 5321 §5.1 — Locating the Target Host

If an empty list of MXs is returned, the address is treated as if it was associated with an implicit MX RR, with a preference of 0, pointing to that host.

Google — MX record values and troubleshooting

Blocklists infra.dnsbl

Whether the sending IP is listed by any of the blocklists receivers actually consult. Our roster is checked against each zone's own documented test point rather than assembled from a web search, because a dead zone answers NXDOMAIN and that reads as "clean".

If it fails: Follow the delisting process on the listing operator's site. A listing on a major zone stops mail outright, so treat it before anything else on the page.

Costs up to 25 points of 100 on our score and up to 3 of 10 on the classic score.

RFC 5782 §2.1 — IP Address DNSxL

Each IPv4 address listed in the DNSxL has a corresponding DNS entry.

RFC 5782 §5 — Test and Contact Addresses

IPv4-based DNSxLs MUST contain an entry for 127.0.0.2 for testing purposes.

Google — Postmaster Tools: reputation and delivery errors

Google — Email sender guidelines

HELO name infra.helo

The name the sending server announces itself as at the start of the SMTP conversation. It has to be a fully qualified domain that resolves.

If it fails: Set your mail server's hostname to a real name in your domain, not to a container id or an internal name.

Costs up to 5 points of 100 on our score.

RFC 5321 §4.1.1.1 — Extended HELLO (EHLO) or HELLO (HELO)

The argument clause contains the fully-qualified domain name of the SMTP client, if one is available.

Google — Email sender guidelines

Google — Requirements for bulk senders (5,000+/day)

MX record infra.mx

Whether the domain in your From header can receive mail. Replies and bounces have nowhere to go without it, and filters treat a sending domain that cannot receive as a bad sign.

If it fails: Publish an MX record for the domain you send from, even if it only routes to a mailbox you read once a month.

Costs up to 5 points of 100 on our score and up to 3 of 10 on the classic score.

RFC 5321 §5.1 — Locating the Target Host

The lookup first attempts to locate an MX record associated with the name.

Google — MX record values and troubleshooting

Reverse DNS infra.rdns

Whether the sending IP resolves back to a hostname, and whether that hostname resolves forward to the same IP. The round trip is the point: a PTR pointing anywhere is easy, a matching pair is evidence the address is yours.

If it fails: Ask whoever owns the IP to set the PTR to a name you control, and make sure that name has an A record pointing back.

Costs up to 12 points of 100 on our score and up to 1.5 of 10 on the classic score.

RFC 1912 §2.1 — Inconsistent, Missing, or Bad Data

Make sure your PTR and A records match. For every IP address, there should be a matching PTR record in the in-addr.arpa domain.

Google — Email sender guidelines

Google — Requirements for bulk senders (5,000+/day)

Transport encryption infra.tls

Whether the message arrived over TLS, and with which cipher. Everything modern negotiates it; a message arriving in the clear says something about the sending setup.

If it fails: Enable STARTTLS on the sending server. Every mainstream platform does this already, so a failure here usually means a self-hosted relay in the path.

Costs up to 5 points of 100 on our score.

RFC 3207 §2 — STARTTLS Extension

The STARTTLS extension to SMTP is laid out as follows:

Google — Require TLS for secure message transport

Google — Requirements for bulk senders (5,000+/day)

Spam engines

What independent content filters make of the message. Two engines rather than one, because a single engine's score is that engine's opinion.

AI judge spam.ai_judge

A model estimates how a modern machine-learning filter would treat the message, from the technical findings and the content measurements. It sees the facts, not the body text.

If it fails: Detail only on its own. Its estimate feeds the combined verdict below.

Shown for detail. Never scored.

Combined verdict spam.panel

One number from the engines that answered, weighted so the loudest is not simply averaged away. SpamAssassin and Postmark count as a single vote because they share a rule base.

If it fails: Work through the individual findings. This row moves when they do.

Costs up to 25 points of 100 on our score.

Google — Why Gmail marks messages as spam

How this score is calculated

Postmark SpamCheck spam.postmark

A third opinion, off by default. Its endpoint takes the whole message and we cannot redact any of it without destroying what is being measured, so switching it on means accepting that every tested message is copied to a third party.

If it fails: Nothing to do. When it is off the check reports that it is off, which is not the same as a pass.

Shown for detail. Never scored.

Rspamd spam.rspamd

A second, independently developed filter. It disagrees with SpamAssassin often enough to be worth asking, which is the reason it is here.

If it fails: Detail only. This engine's opinion is folded into the combined verdict rather than scored on its own.

Shown for detail. Never scored.

Content

The message itself: its structure, its links, its images, the things a filter reads before it decides.

Image alt text content.alt_attributes

Whether images carry alt attributes. Mail clients block remote images by default, so for the first few seconds the alt text is your message.

If it fails: Write alt text that carries the meaning, and never leave the main visual without one.

Costs up to 4 points of 100 on our score and up to 0.5 of 10 on the classic score.

Google — Email sender guidelines

Script and iframe content.forbidden_tags

Whether the HTML contains tags no mail client will run. They are stripped at best and treated as an evasion signal at worst.

If it fails: Remove script, iframe, object and embed. Anything interactive belongs behind a link.

Costs up to 10 points of 100 on our score and up to 1 of 10 on the classic score.

Google — Email sender guidelines

Text to HTML balance content.html_text_ratio

How much of the message is markup against how much is readable text. A page of markup wrapped around one sentence is a shape filters recognise.

If it fails: Write a text part that says what the HTML says, rather than a placeholder.

Costs up to 3 points of 100 on our score and up to 0.3 of 10 on the classic score.

RFC 2046 §5.1.4 — Alternative Subtype

Systems should recognize that the content of the various parts are interchangeable.

Google — Why Gmail marks messages as spam

Text and HTML parts content.html_version

Whether the message carries a plain text alternative alongside the HTML. Some filters weigh its absence, and every screen reader wants one.

If it fails: Send multipart/alternative with a real text version, not an empty part or a line saying to view it in a browser.

Costs up to 5 points of 100 on our score.

RFC 2046 §5.1.4 — Alternative Subtype

The "multipart/alternative" type is syntactically identical to "multipart/mixed", but the semantics are different. In particular, each of the body parts is an "alternative" version of the same information.

Google — Email sender guidelines

HTML size content.html_weight

How large the HTML part is. Gmail clips a message past roughly 102 KB and hides the rest behind a link, which takes your unsubscribe footer with it.

If it fails: Trim inline CSS and repeated style blocks (most templates fit in a third of the limit once the unused rules are gone).

Costs up to 3 points of 100 on our score and up to 0.3 of 10 on the classic score.

Google — Email sender guidelines

Image weight content.images_weight

The total size of the images the message pulls in. Heavy images make a message slow on a phone, and image-only mail is a shape filters treat with suspicion.

If it fails: Compress them and make sure the message still reads with images off.

Costs up to 3 points of 100 on our score and up to 0.3 of 10 on the classic score.

Google — Email sender guidelines

Attachment scanning content.malware

Whether attachments carry known malware. On deployments where the scanner is switched off, this reports that it did not run rather than reporting clean.

If it fails: If this fires, stop sending and find out what is on the machine that built the message.

Costs up to 60 points of 100 on our score.

Google — Why Gmail marks messages as spam

ClamAV — how detection works

Preheader content.preheader

The preview line a client shows next to the subject. Without one it shows whatever comes first in the body, which is usually a view-in-browser link.

If it fails: Add a hidden preheader block as the first element of the body.

Costs up to 2 points of 100 on our score.

Google — Email sender guidelines

Subject line content.subject

Length, capitalisation and the patterns filters score. We measure the decoded subject, so a Cyrillic or CJK line is judged as text rather than as its encoding.

If it fails: Keep it under about 60 characters, drop the shouting and the exclamation marks.

Costs up to 3 points of 100 on our score.

RFC 5322 §2.2 — Header Fields

Header fields are lines beginning with a field name, followed by a colon (":"), followed by a field body, and terminated by CRLF.

RFC 2047 §2 — Syntax of encoded-words

An 'encoded-word' is defined by the following ABNF grammar.

Google — Why Gmail marks messages as spam

Shortened links content.url_shortener

Whether links go through a public shortener. Shorteners hide the destination, which is exactly what filters are trained to distrust.

If it fails: Link your own domain, or use your platform's tracking domain on a subdomain of yours.

Costs up to 5 points of 100 on our score and up to 0.5 of 10 on the classic score.

Google — Why Gmail marks messages as spam

Bulk sender rules

The requirements Gmail and Yahoo publish for anyone sending in volume. These apply to mailings and are skipped for messages that do not look like one.

DMARC policy published compliance.dmarc_present

Whether the From domain publishes a DMARC record at all, separately from whether this message passed it. Gmail and Yahoo require one from bulk senders.

If it fails: Publish a record. p=none is enough to satisfy the requirement and gives you reports to work from.

Costs up to 6 points of 100 on our score.

RFC 7489 §6.3 — General Record Format

p: Requested Mail Receiver policy (plain-text; REQUIRED for policy records).

Google — Requirements for bulk senders (5,000+/day)

Yahoo — Sender requirements and recommendations

List-Unsubscribe compliance.list_unsubscribe

Whether the message carries an unsubscribe header a mail client can act on. Gmail and Yahoo require it from bulk senders, and its absence is filtered on regardless of everything else.

If it fails: Add a List-Unsubscribe header with an HTTPS URI. Every sending platform can do this.

Costs up to 10 points of 100 on our score and up to 1 of 10 on the classic score.

RFC 2369 §3.2 — List-Unsubscribe

The List-Unsubscribe field describes the command (preferably using mail) to directly unsubscribe the user (removing them from the list).

Google — Requirements for bulk senders (5,000+/day)

Yahoo — Sender requirements and recommendations

One-click unsubscribe compliance.one_click_unsubscribe

The stricter form: an HTTPS URI, a "List-Unsubscribe-Post" header, and a single valid DKIM signature covering both headers. All three, or the receiver does not show the button.

If it fails: The usual miss is the signature: platforms sign "List-Unsubscribe" and forget "List-Unsubscribe-Post". Both header names have to appear in the h= tag of the same signature.

Costs up to 8 points of 100 on our score.

RFC 8058 §4 — Additional Requirements

The List-Unsubscribe and List-Unsubscribe-Post headers MUST be covered by the signature and included in the "h=" tag of a valid DKIM-Signature header field.

RFC 8058 §3.1 — Mail Senders

The List-Unsubscribe header field MUST contain one HTTPS URI.

Google — Requirements for bulk senders (5,000+/day)

Yahoo — Sender requirements and recommendations

Recommendations

Worth doing and never scored. Nothing in this section can cost points, which is a product decision the tests enforce.

BIMI advisory.bimi

Whether the domain publishes a BIMI record, which puts a logo next to your messages in some clients. It needs an enforcing DMARC policy first, and a verified mark certificate that costs money.

If it fails: Worth doing once DMARC is at quarantine or reject and the volume justifies the certificate.

Advisory. Costs nothing.

BIMI — draft specification, not yet an RFC

DKIM key age and length advisory.dkim_key_rotation

The length of the signing key and how long it has been in use. Short keys are cheaper to attack offline every year that passes.

If it fails: Move to 2048 bits and rotate on a schedule. Publish the new selector, switch signing to it, then retire the old one.

Advisory. Costs nothing.

RFC 8301 §3.2 — Key Sizes

Since short RSA keys more easily succumb to off-line attacks, Signers MUST use RSA keys of at least 1024 bits for all keys. Signers SHOULD use RSA keys of at least 2048 bits.

Google — Turn on DKIM for your domain

DNSSEC advisory.dnssec

Whether the domain is signed. SPF, DKIM and DMARC all live in DNS, so an attacker who can forge DNS answers can forge all three.

If it fails: Enable it at your registrar. It is usually one switch, and the registrar handles the rest.

Advisory. Costs nothing.

RFC 4033 §2 — Definitions of Important DNSSEC Terms

Authentication Chain: An alternating sequence of DNS public key (DNSKEY) RRsets and Delegation Signer (DS) RRsets

MTA-STS advisory.mta_sts

Whether the domain publishes a policy telling other servers to refuse unencrypted delivery to you. It protects mail sent to you rather than mail you send.

If it fails: Publish the TXT record and the policy file over HTTPS (an afternoon of work, and it closes a downgrade attack).

Advisory. Costs nothing.

RFC 8461 §3 — Policy Discovery

To discover if a recipient domain implements MTA-STS, a sender need only resolve a single TXT record.

TLS reporting advisory.tls_rpt

Whether the domain asks for reports when somebody fails to deliver to it over TLS. Pairs with MTA-STS: the policy without the reporting leaves you unable to tell whether it is working.

If it fails: Add the TXT record with an address that receives the daily reports.

Advisory. Costs nothing.

RFC 8460 §3 — Reporting Policy

A domain publishes a record to its DNS indicating that it wishes to receive reports.