Under attack? Get incident response help

info@angelforce.eu
Email security

SPF, DKIM and DMARC explained - a safe path to p=reject

How SPF, DKIM and DMARC stop others sending email as your domain, how to move from p=none to p=reject safely, and the mistakes that break mail.

Also in:TürkçeDeutschFrançaisEspañolItalianoPolskiNederlandsEesti

Illustration: SPF, DKIM and DMARC explained - a safe path to p=reject

Anyone can type your domain into the From line of an email. SPF, DKIM and DMARC let the receiving server check whether a message really came from you, and tell it what to do when it did not. Set up with care, they make exact-domain spoofing much harder. Rushed, they can block your own invoices.

What each mechanism does

SPF (Sender Policy Framework, RFC 7208) is a DNS TXT record that lists the servers allowed to send mail for a domain. The receiver compares the connecting server's IP address with that list. SPF checks the envelope sender (the MAIL FROM and HELO identities), not the From address the recipient sees.

DKIM (DomainKeys Identified Mail, RFC 6376) adds a cryptographic signature to each message. The d= tag names the signing domain and s= names a selector. The public key is published in DNS at selector._domainkey.domain. A valid signature shows that the signed parts of the message have not changed since that domain signed it.

DMARC ties both to the visible From domain. A revised version was published in May 2026 as RFC 9989, a Standards Track document that replaces RFC 7489. A DMARC record states your policy and asks receivers to send you reports.

MechanismWhat it provesPublished atGap when used alone
SPFThe sending IP is authorised for the envelope domainThe domain itselfSays nothing about the From address people read
DKIMA domain vouches for the messageselector._domainkey.domainThe signing domain can be any domain
DMARCSPF or DKIM passed for a domain that matches the From domain_dmarc.domainDepends on SPF and DKIM being right first

Alignment is the part people miss

A message passes DMARC when SPF or DKIM passes and the authenticated domain aligns with the From domain. Relaxed alignment, the default, accepts a match on the organisational domain, so mail.example.eu aligns with example.eu. Strict alignment (adkim=s or aspf=s) requires an exact match.

Third-party senders are where this usually goes wrong. A newsletter platform might use an envelope domain such as bounces.platform.example. SPF passes for the platform's domain, but that domain does not align with example.eu, so it does nothing for your DMARC result.

The fix is to have the platform sign with DKIM using d=example.eu, or to configure a custom return-path on one of your own subdomains. RFC 9989 recommends that domain owners use both SPF and DKIM. That way, one can still carry the result when the other fails, for example after forwarding.

What the records look like

The examples below use a documentation IP address and a placeholder provider. Replace them with your own values.

example.eu.                    TXT  "v=spf1 include:spf.mail-provider.example ip4:203.0.113.25 ~all"
s2026._domainkey.example.eu.   TXT  "v=DKIM1; k=rsa; p=MIIBIjANBgkqh..."
_dmarc.example.eu.             TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.eu"

The DMARC record above is in monitoring mode. It asks for aggregate reports but requests no action on failing mail. Aggregate reports, now specified in RFC 9990, show which servers send mail using your domain and whether they pass.

For DKIM keys, RFC 6376 requires RSA keys of at least 1024 bits for long-lived keys. Google requires at least 1024 bits for mail to personal Gmail accounts and recommends 2048 bits where your provider supports it.

A safe rollout from p=none to p=reject

  1. List every sender. Include your mail platform, CRM, invoicing and payroll systems, helpdesk, website forms, and devices such as scanners that email documents.
  2. Configure SPF and DKIM for each one. Ask each service to sign with DKIM under your own domain wherever it allows it.
  3. Publish p=none with a rua address. RFC 9989 describes this as the usual starting point, so that you can find senders you missed during setup.
  4. Read the reports and fix gaps. Give it at least several weeks, and longer if you have monthly or quarterly mail runs such as payroll or annual statements.
  5. Move to p=quarantine, then p=reject. RFC 9989 removed the old pct tag. Its replacement is test mode: t=y asks receivers to apply the policy one level lower, so p=reject; t=y is handled as quarantine.
  6. Cover subdomains and parked domains. The sp tag sets the policy for existing subdomains, and the new np tag covers subdomains that do not exist.

Treat t=y as a softening, not a guarantee. Both RFC 7489 and RFC 9989 tell receivers to ignore tags they do not recognise. A receiver that has not yet adopted the new specification may therefore apply your published policy in full.

For step 6, a domain that never sends mail should say so explicitly. Publish an SPF record that authorises nobody and a reject policy:

parked-example.eu.                              TXT  "v=spf1 -all"
_dmarc.parked-example.eu.                       TXT  "v=DMARC1; p=reject; rua=mailto:dmarc-reports@example.eu"
parked-example.eu._report._dmarc.example.eu.    TXT  "v=DMARC1"

The third record matters because the reports go to a different domain. RFC 9990 requires receivers to check that the destination domain has agreed to accept reports for the policy domain before sending them.

Large mailbox providers already expect this work. Since 1 February 2024, Google has required bulk senders (more than 5,000 messages a day to Gmail) to use SPF, DKIM and DMARC with alignment. A policy of p=none meets that minimum, but it does not protect your domain.

Common mistakes

Two SPF records

A domain may publish only one SPF record. If a receiver finds more than one, the SPF result is permerror rather than pass. When you add a new service, merge its include into the existing record instead of creating a second one.

More than ten DNS lookups

RFC 7208 limits SPF evaluation to 10 terms that cause DNS queries: include, a, mx, ptr, exists and the redirect modifier. Includes nested inside your includes count as well. Go over the limit and the result is permerror.

The ip4, ip6 and all terms do not count, so listing your own servers by address helps. Remove includes for services you no longer use. The RFC also suggests limiting "void lookups", queries that return no answer, to two.

+all and ?all

The all mechanism always matches, and its qualifier decides the result. +all therefore authorises every server on the internet, so never publish it. ?all returns neutral, which RFC 7208 says must be treated exactly like having no SPF result. Use ~all (softfail) or -all (fail).

Which of the two? The original DMARC specification (RFC 7489, Section 6.7) notes that rejecting on an SPF fail prevents the receiver from evaluating DKIM. That can hurt forwarded mail, where SPF fails but the DKIM signature is still valid. Once DMARC is enforcing, ~all lets DMARC make the final decision.

Ignoring forwarding and mailing lists

A forwarded message arrives from the forwarder's IP address, which is not in your SPF record. A DKIM signature usually survives forwarding if the message is not changed. Mailing lists that edit the subject or add a footer can break it, though. This is why reliable DKIM signing under your own domain matters more than SPF when you move to p=reject.

Using ptr

RFC 7208 says the ptr mechanism should not be published. It is slow, less reliable, and still counts towards the lookup limit.

Enforcing without reading reports

Jumping straight to p=reject is an easy way to block your own password resets, invoices or support replies. The reports tell you which senders you forgot. Read them before you enforce, and keep reading them afterwards, because new services get added.

Where to start

  • Check what your domain publishes today with our email security checker.
  • Build or tidy your records with the SPF and DMARC generator.
  • Write down every system that sends mail as your domain. You will need this list before enforcing.
  • Publish p=none with a reporting address now, and book a date to review the first reports.
  • Add v=spf1 -all and a p=reject DMARC record to every domain you own that does not send mail.

If you would rather hand over report analysis and the move to enforcement, our managed security service can help with both.

How we can help

SPF and DMARC generator

Build correct SPF and DMARC records for your domain and check an existing SPF record.

Contact us
AngelForce team

Written by the AngelForce team: security consultants with CEH, LPT Master and CISA certifications who test, monitor and defend systems for organisations across Europe and Türkiye.

Written with AI assistance from public sources listed below, and reviewed by the AngelForce team before publication.

Sources

  1. datatracker.ietf.org/doc/html/rfc7208
  2. datatracker.ietf.org/doc/html/rfc6376
  3. datatracker.ietf.org/doc/html/rfc9989
  4. datatracker.ietf.org/doc/html/rfc7489
  5. datatracker.ietf.org/doc/html/rfc9990
  6. support.google.com/a/answer/81126

Articles about Email security

Tell us what you need to protect

Describe your environment and what you want to achieve. We will reply by email.

Contact us
info@angelforce.eu

AngelForce OÜ · Tallinn, Estonia