The Email Authentication Problem

If you’ve ever spent hours fighting with email servers, getting DKIM signatures to work, or wondering why your perfectly legitimate emails end up in spam folders, you’re not alone. Email authentication is one of those things that should be straightforward but turns into an absolute nightmare when you actually try to implement it properly.

This guide covers the complete process of setting up SPF, DKIM, and DMARC authentication, with a focus on the real-world problems you’ll encounter — particularly with DKIM signing in Exim4 environments. Every technical claim here is accurate and defensible. Where the correct answer is “it depends,” we’ll say so.

What You’ll Learn

  • How SPF, DKIM, and DMARC actually work together
  • Setting up DKIM signing with Exim4, including the tainted filename problem introduced in Exim 4.94
  • Troubleshooting the most common configuration problems with specific log evidence
  • DNS record configuration that actually works, with flag-by-flag explanations
  • Modern considerations for IPv6, subdomain handling, MTA-STS, and BIMI

SPF Records: The Foundation

SPF (Sender Policy Framework) is the simplest of the three authentication methods — but don’t let that fool you. There are plenty of ways to get it wrong, and the failures are not always obvious. SPF tells receiving mail servers which IP addresses are authorised to send email for your domain, by publishing a DNS TXT record.

Basic SPF Setup

Create a TXT record for your domain:

v=spf1 ip4:192.0.2.1 include:_spf.google.com ~all

This authorises a specific IPv4 address and Google’s mail servers to send on behalf of your domain. The ~all at the end means “soft fail” — mail from unlisted sources is marked suspicious but not outright rejected.

Understanding SPF Qualifiers

The qualifier at the end of your SPF record determines what happens when a sending IP is not in your list:

  • +all (pass) — Allow everything. Provides no protection whatsoever. Never use this.
  • ~all (soft fail) — Mark as suspicious but deliver anyway. Use this during initial rollout.
  • -all (hard fail) — Reject email from any unauthorised source. Use this once all legitimate senders are confirmed.
  • ?all (neutral) — No policy stated. Effectively the same as no SPF record for practical purposes.

Start with ~all whilst you monitor DMARC reports, then move to -all once you’re confident all legitimate sending sources are covered.

IPv6 Considerations

If any part of your email infrastructure uses IPv6 addresses, they must be included in your SPF record. Many modern mail servers prefer IPv6 when it is available, so an absent IPv6 entry will cause legitimate mail to fail SPF:

v=spf1 ip4:192.0.2.1 ip6:2001:db8::1 include:_spf.google.com ~all

SPF Gotchas That Will Bite You

The 10 DNS Lookup Limit: SPF has a hard limit of 10 DNS lookups per evaluation. Each include:, a, mx, ptr, and exists mechanism counts towards this limit. The ip4:, ip6:, and all mechanisms do not, because they require no DNS resolution. Exceeding 10 lookups returns a PermError, which causes DMARC to treat SPF as failed — even if your record is otherwise correct. Use an SPF validator such as MXToolbox to count your lookups before publishing.

A record like this is a common way to exceed the limit:

# 11 includes = PermError — all legitimate mail may be affected
v=spf1 include:_spf.google.com include:sendgrid.net include:mailchimp.com
  include:salesforce.com include:zendesk.com include:hubspot.com
  include:constantcontact.com include:awsses.com include:mailgun.org
  include:postmarkapp.com include:mandrillapp.com -all

Multiple SPF Records: You may only have one SPF record per domain. If multiple TXT records exist starting with v=spf1, the SPF check returns PermError and all of them are ignored. If you’ve inherited a domain or migrated hosts, check for duplicates before adding a new record.

SPF Record Flattening: When you hit the 10 lookup limit, one option is to “flatten” your record — resolve all include: targets to their actual IP addresses and list them directly using ip4: and ip6: mechanisms:

v=spf1 ip4:192.168.1.0/24 ip4:10.0.0.0/8 ip6:2001:db8::/32 -all

The significant downside: when third-party services change their IP ranges (which they do, without much notice), your flattened record immediately becomes wrong and legitimate mail starts failing. If you flatten, you must monitor for IP range changes from every service you’ve inlined. Automated SPF flattening services exist for this reason.

Using Subdomains: A cleaner long-term solution is to send different types of email from different subdomains, each with its own focused SPF record:

  • newsletters.yourdomain.com — marketing email via your ESP
  • support.yourdomain.com — customer service mail
  • noreply.yourdomain.com — automated notifications

Each subdomain gets its own SPF record with only the relevant senders, keeping lookup counts low and records easy to maintain.

DKIM: The Cryptographic Layer

DKIM (DomainKeys Identified Mail) adds a cryptographic signature to outgoing email. The receiving server can verify that the message genuinely originated from your domain and that the content was not modified in transit. It involves key generation, DNS publication, and mail server configuration that must all align precisely — one wrong element and verification fails silently.

The DKIM Process in Detail

  1. Key Generation: You create a public/private RSA key pair (2048-bit minimum — see below).
  2. DNS Publication: The public key is published as a DNS TXT record under a selector subdomain.
  3. Message Signing: Your mail server signs outgoing emails with the private key, covering specified headers and the message body.
  4. Header Insertion: The signature, selector reference, and algorithm details are added as a DKIM-Signature header.
  5. Verification: The receiving server fetches your public key from DNS using the selector in the header and verifies the signature.

DKIM does not verify who sent the email — it verifies that the domain owner’s mail server signed it and that the signed content was not altered. It is a content integrity check tied to a domain, not an identity check.

DKIM with Exim4: Common Failure Points

Exim4 DKIM configuration has several places where things can go wrong silently. Here are the most common, with specific evidence to look for in your logs.

Problem 1: Wrong Transport Configuration

DKIM signing is configured per-transport in Exim4. If your DKIM configuration is on the wrong transport — one that isn’t actually handling your outgoing mail — messages will be sent unsigned without any error. Check your logs to confirm which transport is being used:

grep "=>" /var/log/exim4/mainlog | grep "T="

Look for entries like:

2025-08-06 10:30:45 1abc123-000ABC-XY => user@example.com R=remote_route T=remote_smtp H=smtp.example.com [192.0.2.1]

The T=remote_smtp value is the transport name. Your DKIM configuration must be in that transport block, not a different one.

Problem 2: Tainted Filename Errors (Exim 4.94 and Later)

From Exim 4.94 onwards, Exim introduced a taint-tracking security mechanism. Any data that originates from an external source — such as email headers or envelope addresses — is considered “tainted” and cannot be used directly in file paths or system calls. Since the sending domain comes from the email’s From header, it is tainted, and using it directly in a DKIM private key path produces this error:

Tainted filename '/etc/exim4/domains/yourdomain.com/dkim.pem'
unable to open file for reading: /etc/exim4/domains/yourdomain.com/dkim.pem

The Old Way (broke in Exim 4.94):

dkim_private_key = /etc/exim4/domains/${lc:${domain:$h_from:}}/dkim.pem

This fails because $h_from is tainted — it comes from the email header.

The Correct Way — using a lookup to untaint:

The solution is to validate the domain against a trusted source before using it in a file path. A dsearch lookup checks whether the domain exists as a directory name under a specified path. If it does, the returned value is considered untainted — because it came from your filesystem, not from the email. If it doesn’t exist, the lookup returns the fallback value (0 in this case), which prevents signing without an error.

# In your transport configuration:
# dsearch checks whether the lowercased From domain exists as a directory
# under /etc/exim4/domains. If found, $value holds the untainted path.
# If not found, the fallback "0" disables signing for that domain.

dkim_domain      = ${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains}{$value}{}}
dkim_selector    = mail
dkim_private_key = ${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains}{$value/dkim.pem}{0}}
dkim_canon       = relaxed/simple
dkim_strict      = 0

For this to work, each domain must have its own subdirectory under /etc/exim4/domains/ containing the private key file. The directory name must match the lowercase domain exactly:

/etc/exim4/domains/
    yourdomain.com/
        dkim.pem
    anotherdomain.com/
        dkim.pem

Important: The dsearch lookup type searches for a directory matching the key. It is not the same as lsearch, which searches a flat text file for a matching line. Do not mix them up — using lsearch syntax with a dsearch lookup, or vice versa, will fail silently or produce unexpected results.

Problem 3: Mismatched Public and Private Keys

If you regenerate a private key without updating the corresponding DNS record — or copy a key file to the wrong location — DKIM signatures will be present in the email headers but will fail verification. This is a silent failure: the email is delivered, but DMARC will treat DKIM as failed.

Verify that your private key and DNS record are in sync:

Extract the public key from your private key:

# Modern OpenSSL (3.x preferred):
openssl pkey -in /etc/exim4/domains/yourdomain.com/dkim.pem -pubout -outform DER | openssl base64 -A

# Legacy OpenSSL (also works):
openssl rsa -in /etc/exim4/domains/yourdomain.com/dkim.pem -pubout -outform DER | openssl base64 -A

Fetch your DNS record:

dig +short TXT mail._domainkey.yourdomain.com

The base64 string after p= in the DNS record must match the output from the openssl command exactly, with no spaces or line breaks. Any difference — including whitespace — means verification will fail.

Generating DKIM Keys

mkdir -p /etc/exim4/domains/yourdomain.com
openssl genrsa -out /etc/exim4/domains/yourdomain.com/dkim.pem 2048
chown Debian-exim:Debian-exim /etc/exim4/domains/yourdomain.com/dkim.pem
chmod 640 /etc/exim4/domains/yourdomain.com/dkim.pem

Why 2048-bit? 1024-bit RSA keys are deprecated and actively rejected by some security-conscious mail receivers. 2048-bit is the current minimum recommended by RFC 8301 (which formally deprecates 1024-bit for DKIM). 4096-bit keys are theoretically stronger but cause practical problems — some DNS providers truncate very large TXT records, and some receiving mail servers have difficulty verifying 4096-bit signatures. 2048-bit is the correct choice for production deployments in 2025.

DNS Record Configuration

Extract your public key to publish in DNS:

openssl pkey -in /etc/exim4/domains/yourdomain.com/dkim.pem -pubout -outform DER | openssl base64 -A

Create a TXT record at mail._domainkey.yourdomain.com (where mail matches your dkim_selector value):

v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_BASE64_HERE

Flag explanations — what each one actually does:

  • v=DKIM1 — Version. Currently the only valid value. Required.
  • k=rsa — Key algorithm. RSA is the standard. Ed25519 is also supported in recent implementations but has limited receiver support in 2025.
  • p= — The base64-encoded public key. Required. An empty p= value revokes the key.
  • s=email — Service type. Restricts this key to signing email only. Optional. If you omit it, the key is valid for any service type. If you include it, any non-email DKIM signing using this key will fail verification. Only add it if you are certain this key will only ever be used for email.
  • t=y — Testing mode. Tells receivers to treat DKIM failures leniently whilst you’re testing. Remove this in production — it signals that your DKIM is not yet fully deployed.
  • t=s — Strict subdomain matching. This is a completely different flag from t=y. It means the d= value in the DKIM signature must match the From domain exactly — subdomains are not permitted to use this key. These two values (y and s) can be combined as t=y:s but serve different purposes entirely.

For a standard production record, the minimal correct form is:

v=DKIM1; k=rsa; p=YOUR_PUBLIC_KEY_BASE64_HERE

Add optional flags only when you understand exactly what they do.

The Full Exim4 Transport Configuration

remote_smtp:
  driver           = smtp
  hosts_require_tls = $host_address
  dkim_domain      = ${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains}{$value}{}}
  dkim_selector    = mail
  dkim_private_key = ${lookup{${lc:${domain:$h_from:}}}dsearch{/etc/exim4/domains}{$value/dkim.pem}{0}}
  dkim_canon       = relaxed/simple
  dkim_strict      = 0

If you’re using an SMTP relay that requires authentication, your transport name may be different (smarthost_smtp or similar — check your logs as described above). The DKIM directives are the same regardless of transport name.

Advanced DKIM: Multiple Selectors and Key Rotation

You can have multiple DKIM keys for the same domain by using different selector names. This enables key rotation without downtime:

# Active key
mail._domainkey.yourdomain.com    TXT "v=DKIM1; k=rsa; p=CURRENT_KEY"

# New key (published before switching, left active after switching)
mail2._domainkey.yourdomain.com   TXT "v=DKIM1; k=rsa; p=NEW_KEY"

Rotation process: Publish the new key in DNS and wait for propagation. Switch your mail server to use the new selector. Leave the old DNS record in place for at least 30 days to cover delayed delivery of messages signed with the old key. Remove the old record after that window.

Rotation frequency: Annual key rotation is the standard recommendation for most deployments. Monthly rotation significantly increases operational overhead — mismanaged rotation is a common cause of DKIM outages. Rotate more frequently only if you have a specific security reason to do so (such as suspected key compromise).

DMARC: Tying It All Together

DMARC (Domain-based Message Authentication, Reporting and Conformance) sits above SPF and DKIM and serves two purposes: it tells receiving servers what policy to apply when authentication fails, and it gives you visibility into who is sending email using your domain through aggregate reports.

Understanding DMARC Alignment

DMARC introduces a concept called alignment. For a message to pass DMARC, at least one of SPF or DKIM must pass, and the domain used in that passing check must align with the domain in the visible From header.

For DKIM, the d= value in the DKIM signature must align with the From domain. For SPF, the envelope sender domain (the MAIL FROM address, also called the Return-Path) must align with the From domain.

There are two alignment modes:

  • Relaxed (adkim=r / aspf=r) — The signing domain can be the From domain or any parent domain. For example, a DKIM signature with d=mail.yourdomain.com aligns with From: user@yourdomain.com in relaxed mode.
  • Strict (adkim=s / aspf=s) — The domains must match exactly. Subdomains do not satisfy strict alignment.

Relaxed alignment is appropriate for most deployments. Strict alignment is rarely needed and can cause legitimate mail to fail if your infrastructure uses sending subdomains.

DMARC Policy Progression

Always start with a monitoring-only policy and move to enforcement only after reviewing reports and confirming all legitimate mail is passing.

Phase 1 — Monitoring (p=none):

v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com; adkim=r; aspf=r

This publishes a policy but takes no action on failures. The rua= address receives aggregate reports, which are the essential tool for understanding your email traffic before moving to enforcement. Monitor for at least 2–4 weeks and until you see no unexplained failures in the reports.

A note on forensic reports (ruf=): The ruf= tag requests per-message forensic reports for failing messages. In 2025, most major receiving systems — including Google and Microsoft — no longer send forensic reports due to privacy concerns. You can include the tag, but do not rely on receiving these reports. Aggregate reports (rua=) are the primary tool.

Phase 2 — Quarantine (p=quarantine):

v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com; pct=25

The pct= tag applies the policy to a percentage of failing messages. Setting pct=25 means only 25% of messages that would be quarantined actually are — the rest are treated as if the policy were p=none. This allows a gradual rollout. Increase to 50, then 75, then 100 as you confirm no legitimate mail is affected.

Note on the pct= tag: pct= applies only to quarantine and reject actions. It has no effect under p=none. Also be aware that the pct tag is proposed for deprecation in the next DMARC RFC revision — some receivers may already ignore it. Do not rely on it as a long-term rollout strategy; use it as a short-term safety net whilst monitoring.

Phase 3 — Reject (p=reject):

v=DMARC1; p=reject; rua=mailto:dmarc@yourdomain.com

Full enforcement. Receiving servers are instructed to reject messages that fail DMARC outright. Only move here once you have verified through aggregate reports that all legitimate mail is passing authentication.

Subdomain Handling

DMARC policies apply to all subdomains of the domain by default unless you specify otherwise with the sp= tag, or publish a separate _dmarc record for the subdomain itself:

# Main domain: reject policy, subdomain policy: quarantine
_dmarc.yourdomain.com TXT "v=DMARC1; p=reject; sp=quarantine; rua=mailto:dmarc@yourdomain.com"

# Override for a specific subdomain — its own record takes precedence
_dmarc.newsletter.yourdomain.com TXT "v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com"

Check all subdomains that send email before moving your main domain to p=reject. A subdomain without its own policy inherits the main domain’s policy via the sp= tag.

DMARC Reports: Your Visibility Into Your Email Ecosystem

Aggregate reports arrive as gzipped XML files and show you which IP addresses are sending email using your domain, and whether they’re passing or failing authentication. Key elements of an aggregate report:

<row>
  <source_ip>192.0.2.1</source_ip>
  <count>150</count>
  <policy_evaluated>
    <disposition>none</disposition>
    <dkim>pass</dkim>
    <spf>pass</spf>
  </policy_evaluated>
</row>

This shows 150 messages from 192.0.2.1 that passed both SPF and DKIM, with no action taken (because the policy is p=none). Any rows showing dkim=fail or spf=fail need investigation before you move to enforcement. Free tools such as DMARC Analyser, Postmark’s DMARC Digests, and Google Postmaster Tools can parse and visualise these reports if you’d rather not read raw XML.

Testing and Troubleshooting

Verification Tools

MXToolbox (mxtoolbox.com) — Test individual DNS records and get instant feedback on syntax and lookup counts. Mail-tester.com — Send a test email and receive a comprehensive analysis including authentication results, spam scoring, and blacklist checks. Google Postmaster Tools — Long-term visibility into your deliverability to Gmail, including domain reputation and authentication pass rates. dig / nslookup — Command-line DNS queries for verifying records as published.

Real-World Testing Process

Step 1 — Verify DNS records are published correctly:

dig +short TXT yourdomain.com | grep spf
dig +short TXT mail._domainkey.yourdomain.com
dig +short TXT _dmarc.yourdomain.com

Step 2 — Check DNS propagation across multiple resolvers:

dig @8.8.8.8 TXT _dmarc.yourdomain.com
dig @1.1.1.1 TXT _dmarc.yourdomain.com
dig @208.67.222.222 TXT _dmarc.yourdomain.com

Different resolvers returning different results indicates the change is still propagating. DNS TTL determines how long cached records remain valid — a low TTL (300 seconds) during initial setup means changes propagate faster.

Step 3 — Send test emails to multiple providers and check the authentication headers:

Authentication-Results: gmail.com;
  spf=pass (google.com: domain of sender@yourdomain.com designates 192.0.2.1 as permitted sender)
    smtp.mailfrom=yourdomain.com;
  dkim=pass header.d=yourdomain.com header.s=mail header.b=abc12345;
  dmarc=pass (p=none sp=none dis=none) header.from=yourdomain.com

All three must show pass. Any failure indicates which layer needs attention.

Common Issues and Solutions

DKIM Signature Present but Failing Verification:

  • Verify the public key in DNS matches the private key using the openssl commands above — this is the most common cause
  • Check for spaces or line breaks in the DNS record’s base64 key — there must be none
  • Confirm the selector in your Exim config (dkim_selector) matches the DNS record prefix exactly
  • Check whether a content filter or relay is modifying the message body after signing — body modifications invalidate the signature
  • Allow up to 48 hours for DNS propagation if you’ve recently updated the record

No DKIM Signature Being Added:

  • Confirm DKIM directives are in the correct transport (check T= in logs)
  • Check file permissions on the private key — it must be readable by the Exim process user (640, owned by Debian-exim on Debian-based systems)
  • Look specifically for “Tainted filename” in /var/log/exim4/mainlog — this is the Exim 4.94+ issue described above
  • Verify the domain directory exists under /etc/exim4/domains/ with the exact correct name (lowercase)

SPF Hard Fail:

  • Verify the sending IP address is included in your SPF record
  • Count your DNS lookups — exceeding 10 produces PermError, which looks like a failure
  • Confirm only one v=spf1 TXT record exists for the domain
  • Include IPv6 addresses if your server sends via IPv6

DMARC Failing Despite SPF and DKIM Passing:

  • This is almost always an alignment issue — check that the d= in the DKIM signature and the envelope sender domain both align with the From header domain
  • Mailing list software and forwarding services frequently break SPF alignment (the envelope sender is rewritten) — in these cases DKIM alignment is the one that must pass
  • Check your adkim= and aspf= settings — strict alignment fails more often than relaxed

Log File Mining

# Look for DKIM-related log entries
grep -i "dkim" /var/log/exim4/mainlog

# Find tainted filename errors specifically
grep -i "tainted" /var/log/exim4/mainlog

# Check which transport handled a specific message
grep "=>" /var/log/exim4/mainlog | grep "T="

# Look for authentication-related rejections
grep -i "auth" /var/log/exim4/mainlog | grep -i "fail"

Modern Considerations and Future-Proofing

MTA-STS: Enforcing TLS for Inbound Email

MTA-STS (Message Transfer Agent Strict Transport Security) allows you to declare that your domain requires TLS-encrypted connections for inbound email delivery, and to specify which mail servers are valid. Sending MTAs that support MTA-STS will fetch your policy and refuse to deliver over unencrypted or invalid TLS connections.

It requires two components: a DNS TXT record and a policy file served over HTTPS.

DNS record at _mta-sts.yourdomain.com:

v=STSv1; id=20250806T103000;

The id= value must change whenever you update the policy file — sending MTAs use it to detect when the policy has changed and must be re-fetched. A timestamp in the format shown is a convenient choice.

Policy file served at https://mta-sts.yourdomain.com/.well-known/mta-sts.txt with Content-Type: text/plain:

version: STSv1
mode: enforce
mx: mail.yourdomain.com
max_age: 604800

On max_age: This value is in seconds. 86400 is only 24 hours — too short for enforce mode, as every sending MTA must re-fetch your policy daily, generating unnecessary load and creating a window where a downtime on your HTTPS server could cause delivery failures. Google’s guidance recommends 604800 (one week) as a reasonable minimum, with 31557600 (approximately one year) for stable, mature configurations. Start at one week and increase as you gain confidence.

Start with mode: testing rather than mode: enforce. In testing mode, the policy is not enforced but violations are reported via SMTP TLS Reporting (below). Switch to enforce only after confirming your TLS configuration is correct across all MX records.

SMTP TLS Reporting

SMTP TLS Reporting (RFC 8460) works alongside MTA-STS. It instructs sending MTAs to report TLS negotiation failures when attempting to deliver to your domain. This gives you visibility into TLS problems you might not otherwise notice.

_smtp._tls.yourdomain.com TXT "v=TLSRPTv1; rua=mailto:tls-reports@yourdomain.com"

BIMI: Brand Indicators in Email Clients

BIMI (Brand Indicators for Message Identification) builds on DMARC to display your brand logo next to messages in supported email clients. It is worth understanding, but also worth setting honest expectations about.

The DNS record format is:

default._bimi.yourdomain.com TXT "v=BIMI1; l=https://yourdomain.com/logo.svg; a=https://yourdomain.com/vmc.pem"

Requirements you must meet before BIMI will display:

  • DMARC policy of p=quarantine or p=reject at pct=100
  • A Verified Mark Certificate (VMC) from an approved Certificate Authority — currently DigiCert or Entrust. VMCs cost approximately £1,000–£1,500 per year and require a registered trademark in the relevant jurisdiction. There is no self-signed or free option.
  • An SVG logo in the specific Tiny PS format, meeting precise dimension and structure requirements published by the BIMI Group.

Client support in 2025: Gmail displays BIMI logos for qualifying senders. Apple Mail supports BIMI from iOS 16 / macOS Ventura onwards. Yahoo Mail supports it. Outlook does not currently display BIMI logos. Support varies and continues to expand.

BIMI is worth pursuing for established brands with high email volumes and a registered trademark. For smaller deployments or personal domains, it is an aspirational feature rather than a near-term priority.

The Bottom Line

When everything is configured correctly, your email headers will confirm it:

Authentication-Results: gmail.com;
  spf=pass (google.com: domain of sender@yourdomain.com designates 192.0.2.1 as permitted sender)
    smtp.mailfrom=yourdomain.com;
  dkim=pass header.d=yourdomain.com header.s=mail header.b=abc12345;
  dmarc=pass (p=reject sp=reject dis=none) header.from=yourdomain.com

And legitimate emails will land in inboxes rather than spam folders.

Email authentication is unforgiving but methodical. Follow this order:

  1. Start with SPF — it’s the simplest layer and provides immediate value. Verify with tools before moving on.
  2. Get DKIM working on a test domain first — a misconfigured key on a production domain can silently cause DMARC failures at scale. Test, verify the key match, confirm signatures in headers, then deploy to production.
  3. Deploy DMARC at p=none immediately — even before SPF and DKIM are perfect. The reports will show you exactly what needs fixing.
  4. Read your DMARC reports before enforcing — every unexplained failure in your reports is a legitimate sender you haven’t accounted for. Rush to p=reject and you will block real mail.
  5. Move to p=reject gradually using pct= — even if pct= is eventually deprecated, it remains a useful short-term safety net whilst transitioning.
  6. Add MTA-STS in testing mode — confirm your TLS configuration is consistent, then switch to enforce.

Authentication is a marathon, not a sprint. The investment in getting it right pays dividends in deliverability, security, and resilience against spoofing and phishing attacks that use your domain. In 2025 it is no longer optional for any domain that sends email seriously.