Set up HubSpot email sending domain on Cloudflare
One setting decides whether this works: the two DKIM records must be set to DNS only, not proxied.
Cloudflare turns proxying on by default — "Proxying is on by default when you onboard a domain via the dashboard" — and CNAME records are proxiable. So the orange cloud appears on your DKIM records automatically, Cloudflare answers lookups with its own IP addresses instead of HubSpot's target, and authentication fails with no error message anywhere. Cloudflare documents this failure using our exact record shape: "The CNAME record you created for domain verification is set to Proxied."
Your TXT records — SPF and DMARC — are safe. Cloudflare is explicit: "Only records used for IP address resolution — A, AAAA, and CNAME records — can be proxied. Other record types (such as MX or TXT) are always DNS-only."
These records let receiving mail servers check that a message claiming to be from you really is from you. They do not guarantee your email reaches the inbox — your content and your sending reputation matter at least as much — but without them, anyone can send email in your name.
What we don't do: we never touch your DNS zone. This guide tells you what to type and where. You're the one who saves it, in your own account, with your own credentials.
Before anything else: pick the right sending domain
HubSpot has an opinion here, and it's a good one. Its recommendation for most customers is to send from a subdomain, not your root domain: "For your email sending domain, you must select a unique subdomain that is separate from the subdomain where you host pages and blog posts. This protects your root domain's email sending reputation."
Its own table calls www.example.com for your site plus @news.example.com for email "HubSpot's recommended path for shared senders", and warns that reusing the same subdomain for both "may [be flagged] as a conflict… As a result, you may notice authentication failures and bounces."
So: decide now whether you're sending as @example.com or @news.example.com. The SPF record goes on whichever domain your From address uses — not automatically on your root.
And check that Cloudflare is actually authoritative. If your nameservers point elsewhere, the values below don't change, but the panel does.
The records to copy and paste
1. DKIM — two CNAMEs, and the orange cloud
| Field | Value |
|---|---|
| Type | CNAME |
| Name | hs1-<your-hub-id>._domainkey (HubSpot shows the exact host) |
| Target | yourdomain-com.hs#a.dkim.hubspotemail.net |
| Proxy status | 🔴 DNS only |
| TTL | Auto |
…and a second one following the same pattern.
What you must replace: everything. The host contains your Hub ID; the target contains your domain with dots turned into dashes, plus an identifier HubSpot assigns. Copy both from the Host and Required data columns in HubSpot.
🔴 Set the proxy status to DNS only before you save. This is the single most common failure of HubSpot on Cloudflare, and Cloudflare explains exactly why: "Proxying a verification CNAME record returns Cloudflare IP addresses instead of the expected verification target. The third-party service cannot match the response and verification fails." Its general rule: "Records used for other purposes, such as CNAME records that prove your domain ownership, should not be proxied."
⚠️ And don't count on Cloudflare to stop you. Cloudflare maintains a list of CNAME targets it refuses to proxy, precisely to prevent this — it includes
dkim2.mcsv.netanddkim3.mcsv.net(Mailchimp),dkim.amazonses.com(Amazon SES),onmicrosoft.com(Microsoft),dkim.intercom.io,zmverify.zoho.comanddkim.infusionmail.com.
hubspotemail.netis not on that list. Mailchimp and SES users get a guardrail here. HubSpot users don't. The orange cloud will appear and nothing will warn you.
One more Cloudflare setting to leave alone: CNAME flattening. It's on by default only for your zone apex, which doesn't affect a
._domainkeyrecord. But on paid plans you can turn on flattening for all CNAME records, and Cloudflare warns: "If a CNAME target is being used to verify a domain for a third-party service, turning on CNAME flattening for all CNAME records may cause the verification to fail." If you're on Free, this doesn't apply to you.
2. SPF — a value nobody can give you
HubSpot asks for an SPF record on your From address domain — and its recommendation is exactly that, a recommendation: "It's also highly recommended that you add HubSpot's SPF record to your From Address domain."
| Field | Value |
|---|---|
| Type | TXT |
| Name | @ (or your sending subdomain) |
| Content | v=spf1 include:<your-hub-id>.spfNN.hubspotemail.net -all |
| TTL | Auto |
What you must replace: the whole include:. HubSpot's own two documentation examples use 123456.spf03.hubspotemail.net and 123456.spf01.hubspotemail.net — the number after spf differs between accounts, as does the Hub ID. There is no universal HubSpot SPF value, and any guide that gives you one is wrong for somebody.
If you already have an SPF record, merge — don't add. HubSpot's instructions are precise: "Add the string in the Required data column after include: to the end of the existing SPF record", and "Verify that the SPF version and -all flag are only included once."
v=spf1 include:_spf.google.com include:123456.spf03.hubspotemail.net -all
⚠️ One SPF record per domain. Always. Two
v=spf1lines mean no SPF at all.
What HubSpot's SPF record does and doesn't do. On HubSpot's shared sending infrastructure, the return path belongs to HubSpot, not to you: "This cannot be customized by senders on HubSpot's shared network" (customising it requires the dedicated IP or transactional add-on). So SPF passes on HubSpot's domain, and your DMARC compliance rides on DKIM alignment — which is what the two CNAMEs above are for. Adding HubSpot's
include:is still worth doing; just don't expect it to be what makes DMARC pass.
⚠️ Ignore HubSpot's "up to 10
include:statements". The real limit in the SPF standard is 10 DNS lookups, not teninclude:statements — and a singleinclude:can cost several lookups. HubSpot's simplification will let you build a record that fails.
HubSpot is right about one thing worth repeating: "Hard coding IP addresses or CIDRs in your SPF record is not recommended." If you inherited a record full of HubSpot IPs, replace them with the
include:.
3. DMARC — required for a green tick here
| Field | Value |
|---|---|
| Type | TXT |
| Name | _dmarc |
| Content | v=DMARC1; p=none; rua=mailto:YOU@YOUR-DOMAIN.com |
| TTL | Auto |
What you must replace: YOU@YOUR-DOMAIN.com with an address you actually read.
HubSpot is unusual: it actually requires DMARC before it calls you authenticated. Its three statuses are "Not authenticated", "Partially authenticated: DKIM has been correctly set up and verified but SPF or DMARC still need to be fully verified", and "Authenticated: DKIM, SPF, and DMARC have all been fully set up and verified." Most sending tools stop at DKIM. This one doesn't, and that's to its credit.
It also validates what you publish, and will show an Invalid DMARC policy error for common mistakes. Worth knowing its rules: only one record beginning v=DMARC1; p must be lower-case none, quarantine or reject; pct=25; not pct=25%;; rua=mailto:you@example.com not rua=you@example.com.
🔴 Keep alignment relaxed. HubSpot: "
adkim&aspf: specifies the alignment mode for DKIM and SPF. These should both be set tor(i.e., a relaxed alignment)." Its troubleshooting table listsadkim=s; aspf=s;under Incorrect. That follows from the return-path point above — on shared sending, strict SPF alignment cannot pass.
⚠️ Don't use the
pct=in HubSpot's example. One of its three example records isv=DMARC1; p=quarantine; pct=25; ruf=mailto:reporting@example.com;, described as quarantining 25 % of failures. That tag was removed from the DMARC standard by RFC 9989, published in May 2026, so servers following the current standard ignore it — you'd get your full policy while believing you were at 25 %. HubSpot half-concedes the point itself: "Note that this parameter is sometimes ignored by certain inbox service providers." Ramp with the policy instead:none, thenquarantine, thenreject.
Why p=none first. It means "watch and tell me". Nobody gets blocked, and you start receiving a list of everything sending in your name. You watch for two to four weeks, confirm every legitimate sender is recognised, and only then tighten.
Useful if you send from a subdomain: "a subdomain will be considered authenticated if there's a DMARC record configured at the root domain level, due to DMARC policy inheritance." One record on your root covers
news.example.comtoo.
4. The MX record you should check — and possibly remove
This one is the opposite of the others: HubSpot doesn't want you to add anything, it wants you to check something isn't there.
"A null MX record, configured as MX 0 ., tells receiving mail servers that your domain doesn't accept incoming email. Some inbox providers reject emails sent from domains with a null MX record. It's recommended to remove a null MX record (MX 0 .) from your domain."
And if your sending subdomain doesn't receive mail: "leave the MX record unset instead of publishing a null MX record. The absence of an MX record doesn't carry the same email rejection risk."
The click path
In HubSpot, to generate your values:
- Click the settings icon in the top navigation bar.
- In the left sidebar, go to Content → Domains & URLs.
- Click the Email Sending tab.
- Top right, click Connect sending domain.
- Enter an email address you send marketing from, then Next, and confirm the domain.
- Either click Sign in with [provider] for automatic setup, or No, I'll set it up manually.
- For each record, click Copy next to the Host and Required data columns.
In Cloudflare:
- In the Cloudflare dashboard, go to the DNS Records page.
- Select Add record.
- Choose the record Type.
- Fill in Name — the prefix only, Cloudflare completes it with your domain — and the value field, which is called Content for TXT and Target for CNAME.
- For the two DKIM CNAMEs, set the proxy toggle to DNS only.
- Select Save.
Then wait, and click Continue setup in HubSpot to re-check.
HubSpot's own Cloudflare instructions are out of date — they still describe a
DNSmenu and a+ Add recordbutton, and they're written for connecting a website domain, not an email sending domain. Use the path above.
@means your root domain in Cloudflare's Name field. For a sending subdomain, type the subdomain label only.
The 3 mistakes we see most often here
1. Leaving the orange cloud on
You paste the two DKIM CNAMEs, they save cleanly, the records look right in Cloudflare — and HubSpot never verifies. The proxy toggle was on by default and you didn't think to change it, because nothing anywhere suggested it mattered.
This is the failure Cloudflare wrote a dedicated troubleshooting page about, using a ._domainkey CNAME as its example. And unlike Mailchimp or Amazon SES users, you get no automatic protection, because hubspotemail.net isn't on Cloudflare's non-proxiable list.
How you spot it: the DKIM records show an orange cloud; a lookup from outside returns Cloudflare IP addresses instead of …dkim.hubspotemail.net.
The fix: click the cloud on each DKIM record until it's grey and reads DNS only. Save, wait twenty minutes, re-check in HubSpot.
2. Copying a HubSpot SPF value from a tutorial
There is no shared HubSpot SPF value. The include contains your Hub ID and a server number that varies — HubSpot's own two documentation examples disagree with each other (spf03 and spf01). Copy someone else's and you've authorised a HubSpot cluster that isn't yours.
How you spot it: your SPF mentions hubspotemail.net but with a Hub ID that isn't yours, or HubSpot's status stays Partially authenticated.
The fix: take the value from the Required data column in your own HubSpot account. And merge it into your existing SPF line rather than adding a second one.
3. Colliding with Cloudflare's own email products
Cloudflare now writes DNS records of its own, and they overlap with everything here. Email Routing — these days under Compute → Email Service → Email Routing — publishes an SPF record on your root domain: v=spf1 include:_spf.mx.cloudflare.net ~all. Cloudflare's own advice if you already have one: "merge them."
So if you've ever turned Email Routing on, adding HubSpot's SPF to your root gives you two v=spf1 records — which means no SPF at all. And you'll have to pick a single final qualifier, since Cloudflare uses ~all and HubSpot's examples use -all.
Cloudflare's newer Email Sending feature goes further and publishes a _dmarc record at p=reject, which can overwrite a DMARC policy you were carefully ramping up.
How you spot it: two SPF records on your root, or a _dmarc record you didn't write showing p=reject.
The fix: one SPF line containing both includes and one final qualifier; one _dmarc record that you control.
⚠️ And don't mix up two opposite traps. Cloudflare's Name field wants the prefix only — typing the full hostname gives you
_dmarc.yourdomain.com.yourdomain.com, and the fix is to shorten it. At some other hosts (OVH, Gandi), the symmetrical trap sits on a CNAME target, where the fix is to add a trailing dot.
A free Cloudflare tool worth knowing about
Cloudflare has DMARC Management, under Email → DMARC Management (not Email Security, which is a different product). It's available on all plans at no cost, it adds its own rua= entry to your DMARC record so it can collect reports for you, it shows whether messages passed or failed DMARC, SPF and DKIM, and it flags SPF records that exceed the ten-lookup limit.
Two limits to know: it "only works with apex domains… and not domains in subdomain setups", and "it may take up to 24 hours to receive your first DMARC report."
We'd rather tell you it exists than pretend otherwise. If all you need is somewhere to send reports, it does that for free. What it won't do is tell you in plain language what to change, warn you when something breaks later, or walk you from p=none to p=reject without cutting off a sender you'd forgotten.
How long before it takes effect
- In Cloudflare: saved immediately. Cloudflare's figure: "DNS changes can take up to 24 hours to propagate globally, but usually complete within 5-15 minutes for domains using Cloudflare DNS."
- Before clicking re-check in HubSpot: HubSpot says "DNS records usually take between 10 and 70 minutes to update, but can take as long as 48 hours", and recommends waiting "at least 20 minutes". Since HubSpot is the one doing the checking, use its numbers.
- On proxied records, TTL is forced to Auto (300 seconds) and can't be edited — but your DKIM records shouldn't be proxied anyway.
- For DMARC reports: the first ones arrive 24 to 72 hours after you publish, then roughly once a day.
Next steps
- How to set up SPF, DKIM and DMARC on Cloudflare
- Set up SendGrid domain authentication on AWS Route 53
- How to move your DMARC policy to p=reject safely
- My emails go to spam even though SPF, DKIM and DMARC pass