Three checks in one minute
- SPF (RFC 7208): a TXT record on the envelope sender's domain lists the servers allowed to send for it. The envelope sender appears as
Return-Pathon the received email. - DKIM (RFC 6376): the provider signs the message; the
d=tag in theDKIM-Signatureheader names the signing domain ands=the selector, whose public key lives ats._domainkey.din DNS. - DMARC (RFC 7489): a policy at
_dmarc.your From domain. It passes when SPF or DKIM passes for a domain that aligns with the From domain.
Why staging gets it wrong
- Staging sends from
staging.example.comorexample-staging.com, a domain nobody added to the provider, so the signature is the provider's own domain and nothing aligns with From. - A separate provider account or sub-account for staging, never set up beyond the defaults.
- An SPF record that lists production's provider but not the one staging uses.
Read the headers of a received email
const res = await fetch(
`https://api.zyntra.app/emails/last?email=${encodeURIComponent(address)}`,
{ headers: { "X-API-Key": process.env.ZYNTRA_API_KEY! } },
);
const { headers, from_address } = await res.json();
console.log("From:", from_address);
console.log("Return-Path:", headers["return-path"]);
console.log("DKIM-Signature:", headers["dkim-signature"]);
// Look for d=<domain> and s=<selector> in the signature.Then check DNS for the domains you found:
dig +short TXT staging.example.com # SPF: v=spf1 ...
dig +short TXT s1._domainkey.example.com # DKIM public key for selector s1
dig +short TXT _dmarc.example.com # DMARC policyWhy it matters even for test mail
Since February 2024 Google requires every sender to Gmail to use SPF or DKIM, and senders of more than 5,000 messages a day to use SPF, DKIM and DMARC with alignment. A staging setup that skips authentication tells you nothing about whether production mail will reach Gmail users, and a test inbox that receives the mail does not prove it would pass those checks. Read the headers.