Don’t get so distracted by DKIM and SPF that you forget the most important DNS record (and you don’t even need SPF on a shared Marketo instance!)

This post isn’t really about SPF, but let me take a moment since it’s one of the few topics I’m not comfy talking about on the Marketo Products Blog. Just can’t toe the party line on this one!

To hammer this home: if you’re on a shared Marketo instance like most users, at best your Marketo SPF entry doesn't matter and at worst you will break your SPF entry completely by needlessly adding

If and only if you have a branded envelope sender (as was the case, to be fair, with the client who inspired this post) then yes, you need an SPF record. But that’s the SPF record for the envelope domain, not for

It’s easy to get distracted by setting up DKIM (everyone still should, don’t get me wrong) and SPF (users with custom envelope sender domains should, but standard shared instances don’t need to) and overlook other DNS tasks.

Surprisingly, those “top o’ the setup checklist” DNS records are more nice-to-haves than must-haves, unless your own org has chosen to publish these policies.

Yes, if your security and risk folks want recipients to authenticate messages that appear to be from your domain, you need DKIM + (if applicable) SPF + DMARC too. But if not, you can do without these records.

(To be clear, not having a record isn’t the same as having a record and failing validation. A broken DKIM signature is very bad, but not signing isn’t. Likewise, failing SPF is very bad, not having an SPF record is meh.[1])

Confusion about who sets up DKIM and SPF, and what they do, can obscure a far more important DNS task that’s vital regardless of your internal policies: the MX record for any domain used to send email.

A recent example

So here I am, troubleshooting a client’s inboxing issues. They’re DKIM-signing their emails using the From: They’re passing SPF for their custom envelope domain They’re sending conservatively and mostly to highly engaged enterprise customers. They even have — don’t ask how, it pays to know people! — a specific bypass entry in one of the major antispam providers. But stuff is going to Spam in Gmail, Office 365, and elsewhere.

I sent some emails to my personal SMTP server, which allows for a deep dive into standard spam checks. It went to Spam there, too. And it logged this:

[SpamAssassin=0.56:(HTML_MESSAGE=0.00,BAYES_00=-1.90,DKIM_VALID=-0.10,SPF_PASS=0.00,SPF_HELO_PASS=0.00,THIS_AD=1.40,URI_TRY_3LD=1.17),Other=5.50:Body=PR,Sender] action SPAM

Never mind the SpamAssassin stuff (it fails a couple of pattern matching tests, but those are counterweighted by SA’s Bayesian filter and it ends up with a score of only 0.56, which is very good). The important part is the Other section where it says it failed PR and Sender.

What Sender tests

PR is is vaguely interesting[1] but doesn’t contribute meaningfully to the score. The problem is Sender. And this is what it means, straight from the IceWarp docs:

This test is both obvious and not-so-obvious and and gets at the core ambiguity of the term “sender”. Sadly, even IceWarp (unlike Marketo, a pretty techie-centric app that usually uses the right technical terms) has fallen into the trap of dumbing things down. And my readers know how much I hate that.

IceWarp uses “sender” to mean 2 things at once. It checks both the envelope sender domain and the From: header domain to see if they can receive mail. And wouldn’t you know it, even though the client had been using for at least a year (don’t blame me, they’re a new client!) there’s no MX record:

; <<>> DiG 9.16.24 <<>> mx
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 63339
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

; EDNS: version: 0, flags:; udp: 512
;                        IN      MX

;; AUTHORITY SECTION:               1800    IN      SOA 2022032450 10800 3600 604800 86400

;; Query time: 75 msec
;; WHEN: Tue Feb 21 23:31:56 Eastern Standard Time 2023
;; MSG SIZE  rcvd: 95

(ANSWER: 0 means no results for the DNS MX query in case that isn’t clear.)

For completeness, there’s no A record either:

; <<>> DiG 9.16.24 <<>> a
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 39659
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1

;                        IN      A

;; AUTHORITY SECTION:               1800    IN      SOA 2022032450 10800 3600 604800 86400

;; Query time: 75 msec
;; WHEN: Tue Feb 21 23:32:10 Eastern Standard Time 2023
;; MSG SIZE  rcvd: 95

With no MX record and no A record (an ancient fallback), there’s no way to receive mail to Thus the receiving mailserver is absolutely right to think the email is spam. Better still would be bouncing the email outright, which you would see in Marketo and might have taken action on months ago! But alas, it’s up to the recipient’s server to accept, reject, silently delete, or folder-ize your messages.


How did the client not realize they were sending from a non-emailable address and getting penalized for it? Well, unfortunately the Marketo Admin » Email section tells you whether you have the right DKIM record for a domain and whether you’ve include-ed in that domain’s SPF record. (Must reiterate how useless that second check is!) But it doesn’t check if the domain has an MX record.

Sending from an emailable address will always be more important than having DKIM and SPF records. If you have DKIM and SPF records, you don’t want to fail those checks, that’s for sure. But passing those checks won’t counteract failing a “can this sender receive a reply” check. And rightly so.


[1] The log snippet above shows DKIM_VALID (valid DKIM signature) only subtracts a tiny bit from the spam score: -0.10. SPF_PASS (SPF PASS) doesn’t add or subtract: 0.00.

Again, failing DKIM and SPF checks gets you seriously upscored — ideally, mailservers will reject immediately — but not running those checks is basically the same as passing ’em.

[2] PR is actually P and R. P It means “HTML and Text parts didn’t match”, but don’t freak out, it’s not scored enough to matter. R is an old-fashioned test for the number of hops the server went through. More on that another day maybe, but again not important.