You're sending email. Your code is right, the SMTP connection opens — yet mail disappears. Or Gmail answers:
550-5.7.26 Your email has been blocked because the sender is unauthenticated.
These three records (SPF, DKIM, DMARC) exist precisely to solve that. Copy-pasting them without understanding what they do means getting stuck at the first problem.
The problem: email was designed in 1982
In SMTP, the "sender" field is a claim, not a verified identity. Any server can send from any address:
MAIL FROM:<ceo@example-corp.com>
RCPT TO:<victim@example.com>
DATA
...
.
Nothing stops you. That's why spam has existed since the 1990s. SPF, DKIM and DMARC close this gap on three separate layers.
SPF — "may this IP send on behalf of this domain?"
SPF is a TXT record and it checks the sending IP:
example.com. 300 IN TXT "v=spf1 ip4:203.0.113.10 include:_spf.google.com ~all"
Reads as: "203.0.113.10 and IPs covered by Google's SPF may send for example.com; mark the rest as suspicious (~all)."
| Mechanism | Meaning |
|---|---|
ip4:203.0.113.10 | This IP may send |
include:_spf.google.com | Include that domain's SPF too |
a / mx | Hosts in A / MX records may send |
-all | Reject the rest (hard) |
~all | Flag but accept (soft) |
?all | Neutral — no policy |
Common mistake: having two SPF records on a domain. If two v=spf1 TXT records exist, both are considered invalid and SPF is not applied at all. There must be exactly one — when adding a new provider, edit the existing record, don't add a second one.
DKIM — "was the message modified in transit?"
DKIM lets the sending server cryptographically sign the message. The signature goes into the headers:
DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=mail;
h=from:to:subject:date:message-id;
bh=...; b=...
The receiver verifies the signature using the public key in the mail._domainkey.example.com TXT record:
mail._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."
The critical difference from SPF: DKIM is tied to the message, not the IP. Even if the mail is forwarded, the signature remains valid — SPF breaks in that case. That's why Gmail says "SPF or DKIM"; DKIM is more resilient.
DKIM's silent traps
- Wrong key format — OpenSSL 3 defaults to PKCS#8 (
BEGIN PRIVATE KEY); some signing tools cannot read it and skip signing silently. PKCS#1 (BEGIN RSA PRIVATE KEY) is required. - Key regeneration — if a container rebuild generates a new key while DNS still has the old public key, every message falls out of DKIM.
- Selector mismatch — signature says
s=mailbut DNS hasdefault._domainkey: verification fails.
DMARC — "what should happen when SPF/DKIM fail?"
DMARC is a policy layer. It tells receivers what to do based on SPF/DKIM results and enforces that the sending domain aligns with the From: header:
_dmarc.example.com. IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com; pct=100"
| Policy | Meaning |
|---|---|
p=none | Monitor only — do nothing (correct starting point) |
p=quarantine | Send failing mail to spam |
p=reject | Reject failing mail (strictest) |
The rua address receives DMARC reports — weekly XML showing who is trying to impersonate your domain.
Correct order: start with p=none, watch reports for 2-4 weeks, confirm all your legitimate senders pass, then move to quarantine and reject. Starting at reject cuts off senders you forgot about (billing system, CRM, email signature service).
PTR — the fourth, invisible layer
SPF/DKIM/DMARC are defined in DNS; PTR is defined at your IP provider:
$ dig -x 203.0.113.10 +short
mail.example.com.
And forward-confirmed reverse DNS (FCrDNS) is expected: mail.example.com should resolve back to 203.0.113.10. PTR is usually set from your hosting provider's panel — you can't do it yourself.
Testing: does it actually pass?
Verify with three commands:
# SPF
dig +short TXT example.com | grep spf1
# DKIM (replace the selector with yours)
dig +short TXT mail._domainkey.example.com
# DMARC
dig +short TXT _dmarc.example.com
# PTR
dig -x 203.0.113.10 +short
For a definitive answer, send a message and inspect the headers. In Gmail: "Show original" → the Authentication-Results line:
Authentication-Results: mx.google.com;
spf=pass smtp.mailfrom=example.com;
dkim=pass header.d=example.com;
dmarc=pass (p=QUARANTINE) header.from=example.com
If all three say pass, you're done. If one says fail, go back to the matching section above.
You don't have to configure all of this yourself
Writing these three records correctly, rotating DKIM keys and talking to your provider about PTR is not a one-time task — it needs ongoing care.
On Skyversal PaaS that layer is done: 200 emails/day free on every plan, SPF/DKIM/PTR managed on our side, and attaching your own domain is free. We show you the 2 TXT records to add and never touch your MX records — your inbox keeps working.
More: latest updates and technical documentation.