Gmail's sender requirements, for developers: what your application must get right

Google and Yahoo's sender requirements, translated from policy into engineering: SPF and DKIM on the right domains, DMARC, aligned From headers, one-click unsubscribe, TLS, reverse DNS and the spam-rate ceiling — and how to verify each one on a message before it goes out.

The Mailclutch team8 min read

In February 2024, Google and Yahoo started enforcing a shared set of requirements on anyone sending mail to their users. The announcements were written for "bulk senders" and framed around marketing. That framing led a lot of engineering teams to file them under someone else's problem.

They are not. The requirements apply to the domain, not the campaign. If your application sends password resets, invoices and notifications from example.com, and marketing sends newsletters from example.com, the two share a reputation — and the transactional mail is the half that hurts when it goes missing. This is the list, written for the people who own the sending code.

The requirements, in engineering terms

Google's list, condensed and translated:

The requirements, in engineering terms
Requirement Applies to What it means for your code
SPF or DKIM everyone Your sending IPs in SPF, or a DKIM signature — on the From domain or a domain it aligns with.
SPF and DKIM 5,000+/day Both, not either.
DMARC record 5,000+/day _dmarc.example.com exists. p=none satisfies the letter; enforcement is where you should end up.
From header aligned 5,000+/day The domain in From: matches the SPF or DKIM domain (relaxed alignment).
One-click unsubscribe marketing / subscribed mail List-Unsubscribe + List-Unsubscribe-Post headers. Not required on transactional mail.
Honour unsubscribes in 2 days same Backend work, not a header.
Spam rate under 0.3% everyone Measured in Postmaster Tools. Aim under 0.1%.
TLS on the connection everyone Submission on 587/465 with TLS; relay with STARTTLS.
Valid forward and reverse DNS everyone The sending IP has a PTR, and the PTR's name resolves back to the IP.
RFC 5322 formatting everyone Message-ID, Date, a real From, no mangled MIME.
No impersonating Gmail in From everyone Do not send From: you@gmail.com through your own servers.
ARC on forwarded mail forwarders Only if you forward or relay others' mail.

The 5,000-per-day threshold is where several items become mandatory. Below it they are "recommended", which in practice means Gmail scores you on them anyway. Build for the full list.

SPF: which domain, and how many lookups

SPF is a TXT record on a domain listing the hosts allowed to send envelope mail for it. The domain Gmail evaluates is the one in MAIL FROM — the return path — which for most providers is their bounce domain, not yours, unless you set up a custom return path.

example.com.  IN  TXT  "v=spf1 include:_spf.yourprovider.com include:_spf.google.com -all"

Two things to check in code review rather than DNS review:

  • The 10-lookup limit. Every include:, a:, mx: and redirect= costs a DNS lookup, recursively. Past ten, the result is permerror — which Gmail treats as a fail. Providers' includes nest; three providers can exhaust the budget.
  • ~all vs -all. Softfail versus fail. For DMARC purposes both produce an SPF result; for reputation, -all signals you know what you are doing.

SPF also breaks when mail is forwarded, because the forwarder's IP is not in your record. This is why the requirements say SPF or DKIM for small senders, and why DKIM is the one that matters more.

DKIM: sign on your domain, not just the provider's

DKIM is a signature over selected headers and the body, verified against a public key in DNS at <selector>._domainkey.<domain>. The domain in the signature's d= tag is what aligns with From: for DMARC.

Every provider signs mail by default — on their domain. That passes DKIM. It does not align with your From domain, so it does not help DMARC. You need a signature with d=example.com, which means adding the provider's DKIM CNAME records to your DNS and enabling custom DKIM in their dashboard.

Check it on a received message:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=s1;
        h=from:to:subject:date:message-id:mime-version:content-type;
        bh=...; b=...

d=example.com — good. d=mail-provider.net — passes DKIM, fails alignment.

Two engineering details:

  • Key length. 2048-bit RSA. 1024 is treated as weak by Gmail and rejected outright by some validators.
  • Body modification after signing. Anything that touches the body after the signature is computed breaks it — a footer added by a gateway, a tracking-link rewriter, a line-ending normalizer. If DKIM fails on received mail and passes on what your app produced, something in between is editing it.

DMARC: from p=none to enforcement

DMARC ties SPF and DKIM to the visible From header and tells receivers what to do when neither aligns.

_dmarc.example.com.  IN  TXT  "v=DMARC1; p=none; rua=mailto:dmarc-reports@example.com"

p=none meets Gmail's minimum. It also does nothing — it is the monitoring mode. The path is:

  1. p=none with rua= reporting. Collect aggregate reports for two to four weeks.
  2. Every legitimate source that fails alignment gets fixed — custom DKIM, custom return path, or removed.
  3. p=quarantine. Watch the reports.
  4. p=reject.

Enforcement is also the gate for BIMI, if the logo matters to you.

The From header: alignment, and not being Gmail

Alignment means the domain in From: matches — exactly in strict mode, at the organizational level in relaxed mode — the domain that passed SPF or DKIM. Relaxed is the default and is fine. The failure that matters is code-level: an application that sets From: from user input, or from a config value someone changed to a personal address to "test something".

And the specific prohibition: do not send with a @gmail.com From address through your own infrastructure. Gmail's DMARC policy is p=none today but the requirements name this explicitly, and Yahoo's is p=reject. An app that lets a user "send from their own email" is spoofing, as far as the receiver is concerned.

One-click unsubscribe: which mail, which headers

For subscribed mail — newsletters, digests, marketing — Gmail requires RFC 8058 one-click unsubscribe:

List-Unsubscribe: <https://example.com/u/abc123>, <mailto:unsub@example.com?subject=abc123>
List-Unsubscribe-Post: List-Unsubscribe=One-Click

The second header is the one people miss. Without it, the first is just a link; with it, Gmail can unsubscribe the user with one tap by POSTing to the URL. The full implementation — including what your endpoint must accept and why it must not require a login — is in the List-Unsubscribe article.

For transactional mail — receipts, resets, security alerts — the header is not required and is usually inappropriate. The distinction is whether the recipient can meaningfully opt out. Where your application sends both, the mailer needs to know which kind it is sending, per message, and set the headers accordingly.

The spam-rate ceiling

Gmail measures the share of your mail that users mark as spam and publishes it in Postmaster Tools. The rule: stay under 0.3%, and never sustain it; aim under 0.1%. Cross the line and Gmail starts filtering the domain — all of it, transactional included.

For engineering, the levers are:

  • Set up Postmaster Tools for the domain. It is free and it is the only view of the number.
  • Separate marketing and transactional onto subdomains (news.example.com, notify.example.com) so a bad campaign does not drag down password resets. Each subdomain has its own reputation, its own DKIM selector and its own DMARC policy.
  • Make unsubscribing easier than marking as spam. That is what the one-click header is for.

TLS, PTR, and the mechanical checks

The remaining items are infrastructure, and they are the ones a sandbox shows you directly:

  • TLS. Submission on 587 with STARTTLS or 465 with implicit TLS. Your provider handles the relay hop.
  • Reverse DNS. If you run your own MTA, the sending IP needs a PTR record and the PTR's hostname must resolve back to the IP. Cloud IPs come with a generic PTR; set a real one.
  • Message-ID. Every message needs a unique one. Frameworks generate it; hand-rolled SMTP code often does not, and SpamAssassin has a rule for that (MISSING_MID).
  • Date. Present, in the right format, roughly now. Ditto (MISSING_DATE, DATE_IN_PAST_*).
  • A real From. From: noreply@localhost and From: root@ip-10-0-1-4 are not real.

Verifying it before it ships

Every check above can be run on a message before it is sent to a real recipient — if you can see the message as a receiver would. That is what a sandbox in the staging path is for. Point staging at Mailclutch, and each captured message reports:

  • the SPF, DKIM and DMARC results on the message and their alignment with the From domain;
  • the presence and form of List-Unsubscribe and List-Unsubscribe-Post;
  • a SpamAssassin score with the rules that fired;
  • a BIMI lookup on the From domain;
  • the raw headers, so the d=, the selector, the Message-ID and the Date are one click away.

The deliverability score rolls them into a number, but the value is the list underneath it: a pull request that changes the mailer, the From address or the template shows up as a changed result on the next staging send, and the diff says which line.

Checklist

  • SPF record on the return-path domain, under 10 lookups, ending -all.
  • DKIM signing with d= on your own domain, 2048-bit, on every sending source.
  • _dmarc record with reporting, on the apex and every sending subdomain, moving toward p=reject.
  • From: domain aligns with SPF or DKIM; never @gmail.com or @yahoo.com.
  • Subscribed mail carries List-Unsubscribe + List-Unsubscribe-Post; transactional mail does not.
  • Unsubscribes processed within two days.
  • Postmaster Tools set up; spam rate under 0.1%.
  • TLS on submission; PTR on any IP you send from directly.
  • Message-ID, Date, real From on every message.
  • Marketing and transactional on separate subdomains.
  • A sandbox in the staging path, so the above is checked on every send rather than once.

Related articles

Keep reading

All articles

Read about it here, check it on your staging.

See it on your own mail

Point your staging SMTP at Mailclutch and every message comes back with its headers, its spam score and its authentication results — before a customer sees it.

Free plan · no credit card · running in under a minute