Suped

Why is DKIM failing when sending from Salesforce via Gmail?

Published 21 Jul 2025
Updated 4 Jun 2026
9 min read
Summarize with
Salesforce and Gmail DKIM failure article thumbnail.
DKIM fails in this setup because the message body Gmail receives is not the exact body Salesforce signed. In the Salesforce via Gmail route, Salesforce creates and signs the message first, then Google Workspace relays it. If the handoff changes line endings, encoding, MIME boundaries, tabs, spaces, quoted-printable wrapping, or quoted thread content, Gmail recalculates the body hash and gets a different value.
That is why the same message can show SPF pass and DMARC pass while DKIM shows dkim=neutral with body hash did not verify. SPF passes because Google Workspace is authorized to send for the domain. DMARC passes because SPF matches the visible From domain. DKIM still matters, because it proves the signed body survived the route unchanged.
Direct answer
Gmail is not the DKIM signer just because the header says Authentication-Results: mx.google.com. That line only says Gmail evaluated the message. The signer is the domain in d= or header.i, paired with the selector in s=. If the selector is sf1 and the DNS record points at custdkim.salesforce.com, Salesforce signed the message before Google handled it.

Why this route breaks DKIM

The route has two systems doing separate jobs. Salesforce builds the email, applies its DKIM signature for your domain, and hands the result to Google Workspace. Google Workspace then sends the mail out through Gmail infrastructure. That sequence is valid only when the body handed to Google is the same body received by the mailbox.
Flowchart showing Salesforce signing before Gmail checks the final body.
Flowchart showing Salesforce signing before Gmail checks the final body.
DKIM signs selected headers and a canonicalized body hash. Canonicalization tolerates limited whitespace differences, but it does not forgive a materially different MIME body. When Gmail says body hash did not verify, the DNS key was found and the signature could be parsed. The failure is not a missing selector or a wrong public key. The body under bh= no longer matches what arrived.
  1. Salesforce signed: A selector such as sf1 is tied to Salesforce custom DKIM DNS.
  2. Google relayed: The sending IP and SPF result point at Google Workspace.
  3. Body changed: The receiving checker recalculated bh= and got a different value.
  4. DMARC passed: SPF matched the visible From domain, so DMARC did not need DKIM.

What the header is really saying

Start with the raw message, not a summarized checker result. In Gmail, use Show original, then look at Authentication-Results and DKIM-Signature. A DKIM checker confirms the DNS selector, but it does not prove the in-transit body stayed unchanged.
Header pattern to inspecttext
Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@example.com header.s=sf1 header.b=abc123; spf=pass smtp.mailfrom=billing@example.com; dmarc=pass header.from=example.com DKIM-Signature: v=1; a=rsa-sha256; d=example.com; s=sf1; c=relaxed/relaxed; bh=...; b=...
The critical mistake is reading mx.google.com as the signer. It is the host that wrote the result after checking the message. The signer is inside the DKIM signature. If you need the deeper mechanics, the related body hash verification explanation covers why content changes break the hash.
  1. Signer: Use d= or header.i to identify the signing domain.
  2. Selector: Use s= to find the DNS key Salesforce published.
  3. Body hash: Use bh= to prove the received body no longer matches.
  4. Result host: Treat mx.google.com as the evaluator, not the signer.

DKIM checker

Check selector records and public key configuration.

?/7tests passed

Why SPF and DMARC pass anyway

A mixed result is normal here. SPF authenticates the sending IP and envelope sender. If Google Workspace is authorized in SPF for the domain, SPF passes. DMARC then checks whether SPF or DKIM matches the visible From domain. Since SPF matches, DMARC passes even though DKIM is neutral.

Result

Meaning

Action

SPF pass
Google IP accepted
Keep route
DKIM neutral
Body changed
Trace signer
DMARC pass
SPF matched From
Monitor
Policy none
No reject action
Stage policy
Compact reading of the mixed authentication result.
I still treat the DKIM failure as a real issue. SPF is fragile when mail is forwarded, and DMARC enforcement is easier to manage when both SPF and DKIM are healthy. Ongoing DMARC monitoring helps separate one-off test failures from a persistent Salesforce route problem.
Do not chase SPF first
If SPF and DMARC already pass, changing SPF will not fix body hash did not verify. The DKIM failure is about the signed body. Focus on the signer, selector, message source, and the route between Salesforce and Google Workspace.

How I isolate the source

Before changing DNS, I run a whole-domain check with the domain health checker so I know the base DMARC, SPF, DKIM, and DNS records are clean. Then I test the sending path, because the error points at the body after signing.
Salesforce Setup screen showing email relay and DKIM configuration.
Salesforce Setup screen showing email relay and DKIM configuration.
  1. Baseline: Send the same short message directly from Gmail as the same user.
  2. Salesforce direct: Disable Gmail sending for the test and send from Salesforce only.
  3. Relay path: Enable Salesforce through Google Workspace relay and send the same body.
  4. Plain body: Send only hello world with no thread, signature, template, tabs, or footer.
  5. Compare: Save raw source for each message and compare d=, s=, bh=, and body output.
Plain ASCII test messagetext
Subject: DKIM test hello world No signature No quoted thread No footer No tab characters
If plain text passes
The route can preserve a simple body. The failure is then inside the template, message builder, copied content, or thread history.
  1. Template: Remove rich text blocks one at a time.
  2. Encoding: Look for Unicode punctuation, tabs, soft line wraps, and copied content.
  3. Threading: Test a new message without quoted replies.
If plain text fails
The route itself is the likely source. Salesforce signed one body and Google sent or exposed another body to the receiver.
  1. Route: Test Salesforce direct against Salesforce through Google Workspace.
  2. Support: Send Salesforce the raw source and test matrix.
  3. Design: Move DKIM signing to the final outbound system when available.

Fix paths that actually work

The practical fix is to stop signing before a body-changing hop. I also check Salesforce DKIM setup against the exact org and domain, but the header symptom tells me the main question is signing order.

Fix

Use when

Tradeoff

Google signs
Relay rewrites body
Check d=
Salesforce direct
Relay path fails
Avoid relay
Template cleanup
ASCII passes
Retest body
Support ticket
ASCII fails
Include source
Fix options for Salesforce through Gmail DKIM failures.
Do not assume DNS is wrong
A passing selector lookup means the public key exists. A body hash failure means the signed body changed or was canonicalized differently. Replacing the DKIM key only helps when the header points to a key, selector, or CNAME lookup problem.
  1. Ask: Does Salesforce sign before handing mail to Google Workspace relay?
  2. Attach: Raw source for Gmail direct, Salesforce direct, and Salesforce via Gmail.
  3. Prove: Show the failing selector, signing domain, route setting, and timestamp.
  4. Retest: Change one variable, then compare the same raw headers again.

Where Suped fits

Suped's product is the best overall DMARC platform for most teams because it joins the operational pieces that matter after a one-off header test: source attribution, automated issue detection, real-time alerts, hosted DMARC, hosted SPF, and DKIM visibility. For this Salesforce and Gmail case, the useful part is source-level evidence. I want to know which path is passing DMARC through SPF, which path has DKIM body hash failures, and when the failure rate changes after a route change.
Issue steps to fix dialog showing the issue overview, tailored fix steps, and verification action
Issue steps to fix dialog showing the issue overview, tailored fix steps, and verification action
That turns the problem into a short operational loop: identify the source, confirm the failing authentication result, apply the fix, and watch the next reports. Hosted SPF helps when DNS access is slow, hosted DMARC helps with policy staging, and real-time alerts help catch a broken route before it becomes a mail flow incident.
DKIM failure thresholds
How I treat Salesforce via Gmail DKIM failures after a controlled test.
Green
0%
No failing path after the route change.
Watch
1-5%
Small failure rate tied to known tests.
Fix
>5%
Persistent production failures by source.
  1. Source grouping: Salesforce, Google Workspace, and other senders are separated by evidence.
  2. Issue steps: Failures turn into specific fixes instead of a pile of aggregate XML.
  3. Policy staging: Hosted DMARC makes p=none to enforcement changes easier to control.

Views from the trenches

Best practices
Compare Salesforce direct, Gmail relay, and basic Gmail headers before changing DNS.
Test a plain ASCII message first, then add template elements until DKIM fails again.
Track the signing domain and selector so support receives the exact failing path.
Common pitfalls
Treating mx.google.com as the signer confuses result stamping with DKIM signing.
Assuming a valid DNS key proves the message body survived every hop without changes.
Changing SPF when DMARC already passes wastes time on the wrong authentication result.
Expert tips
Ask Salesforce support whether DKIM signing runs before the Google relay handoff.
Disable one sending path at a time so each test isolates the failing route cleanly.
Keep one untouched raw message file so validators can inspect canonicalized body data.
Expert from Email Geeks says the first question is which system created the DKIM signature, since mx.google.com only stamped the authentication result.
2023-08-04 - Email Geeks
Expert from Email Geeks says body hash errors mean the body changed between signing and receipt, so the investigation should move away from SPF.
2023-08-04 - Email Geeks

The cleanest fix

The cleanest fix is to sign after the last body-changing hop. If Salesforce creates the email and Google Workspace relays it, Salesforce needs to hand over an already-normalized body that Google does not rewrite, or Google Workspace needs to be the DKIM signer for the final outbound copy. If a plain hello world test still fails through the relay path, I stop adjusting DNS and open a Salesforce case with raw sources.
  1. Keep: SPF and DMARC passing while you troubleshoot DKIM.
  2. Change: Only one signing or routing variable per test.
  3. Prove: Show Salesforce the failing sf1 signature and a passing control path.
  4. Monitor: Watch source-level DMARC reports after every routing change.

Frequently asked questions

DMARC monitoring

Start monitoring your DMARC reports today

Suped DMARC platform dashboard
What you'll get with Suped
Real-time DMARC report monitoring and analysis
Automated alerts for authentication failures
Clear recommendations to improve email deliverability
Protection against phishing and domain spoofing