Resend verifies a domain by watching public DNS for a
small set of records you publish: an MX and a TXT record on a sending subdomain, plus the DKIM records
Amazon SES generates for you. Nothing else is mandatory. The status
walks from not_started to pending to verified on its own once Resend can read them, and the
domains that never get there are nearly always failing on one of five
specific, fixable mistakes. This guide covers every record, what each
one is for, and each of those five failures.
Why Resend asks for a send subdomain.
When you add a domain, Resend recommends a dedicated sending
subdomain, usually send.example.com, rather than your
apex. Two practical reasons sit behind that recommendation. The first
is reputation isolation: mailbox providers build reputation per
sending domain, so keeping your product email on send.example.com means a bad week of complaints on
marketing mail does not drag down the password reset emails, and
neither one touches the reputation of the human mail your team sends
from the apex.
The second reason is mechanical. The return-path record is an MX, and your apex almost certainly already has MX records pointing at Google Workspace or whatever
handles your inbox. A subdomain sidesteps that collision entirely.
Resend will verify an apex domain if you insist, but you inherit both
problems for no benefit.
The record set.
Here is everything Resend can ask for, with the host written as a
label rather than a full hostname, because that is how most DNS
editors want it. If yours wants the full name, send
becomes send.example.com. Values are generated per
domain, so copy the literal strings from your dashboard rather than
from any guide, including this one.
| Type | Host | Value | Purpose |
|---|---|---|---|
| MX | send | feedback-smtp.<region>.amazonses.com, priority 10 | Return path. Routes bounce and complaint reports back to Resend so they surface as events instead of vanishing. |
| TXT | send | v=spf1 include:amazonses.com ~all | SPF. Authorizes the Amazon SES infrastructure Resend sends through to send mail for the send subdomain. |
| CNAME | <random>._domainkey | <same-random>.dkim.amazonses.com. | DKIM, published as three separate CNAMEs. Lets receivers verify the signature on your mail. Tokens are unique per domain. |
| CNAME | links | links1.resend-dns.com | Optional. Serves open and click tracking from your own domain instead of a shared Resend host. |
| TXT | _dmarc | v=DMARC1; p=none; rua=mailto:dmarcreports@example.com; | Optional for verification, strongly recommended after. Tells receivers what to do when SPF and DKIM alignment fails. |
The first three are what verification actually checks. The tracking
CNAME only matters if you want open and click links served from your
own domain, and DMARC is not part of verification at all. Notice the
SPF include is amazonses.com, not something
Resend-branded: Resend sends through Amazon SES, so the SES include is
correct and there is no _spf.resend.com to look for.
Three DKIM CNAMEs, or one resend._domainkey TXT.
DKIM is the record people get wrong most often, partly because Resend
has shipped two different shapes of it. The current setup is SES Easy
DKIM, which means three CNAME records, not one. Each
has a host of <random>._domainkey and a value of <same-random>.dkim.amazonses.com. where the random
token in the value matches the token in the host. Three records exist
so the key can be rotated without a gap in signing. All three have to
resolve; two out of three is a failed check.
Older and classic setups instead show a single TXT record
at resend._domainkey whose value is the public key
itself. If that is what your dashboard shows, that is what you
publish. Neither shape is wrong, and you do not get to choose: publish
exactly what the dashboard hands you, because the check looks for that
and nothing else. The
Resend DKIM selector guide
goes deeper on the selector itself and how to read the key value.
One constraint worth knowing before someone on your security team asks: the DKIM keys here are 1024-bit. 2048-bit keys are not supported. That is a property of the underlying SES Easy DKIM setup, not a toggle you have missed in the dashboard.
Regions change exactly one value.
Resend lets you choose a region when you create the domain. As of
mid-2026 the options are us-east-1, eu-west-1, sa-east-1, and ap-northeast-1. The only thing the region changes in your
DNS is the return-path MX value, which becomes feedback-smtp.<region>.amazonses.com. The SPF string
is the same everywhere, the DKIM CNAME pattern is the same everywhere,
and the tracking CNAME is the same everywhere. Copying an MX value out
of a guide written by someone in another region is a guaranteed failed
check that looks exactly like a propagation problem, so copy it from
your own dashboard.
DMARC comes after verification, not before.
DMARC is not required to verify a domain and it is not required to
send. Get SPF, DKIM, and the return-path MX green first, then publish
DMARC as a TXT record on the host _dmarc.
Start in monitoring mode so you can see what is happening without
affecting delivery, then tighten in two steps once the reports are
clean:
_dmarc TXT "v=DMARC1; p=none; rua=mailto:dmarcreports@example.com;" _dmarc TXT "v=DMARC1; p=quarantine; rua=mailto:dmarcreports@example.com;" _dmarc TXT "v=DMARC1; p=reject; rua=mailto:dmarcreports@example.com;"
Publish one at a time, in that order, sitting at each stage long
enough to read a few days of aggregate reports. Jump straight to p=reject and some forgotten system that sends as your
domain, an invoicing tool or a helpdesk, starts getting silently
dropped. For how the three protocols fit together, see
SPF, DKIM, and DMARC for SaaS
.
The five reasons verification stalls.
Cloudflare proxying is on. A record with the orange cloud enabled is proxied, which means it does not answer as a plain DNS record and Resend cannot read it. Every record in the table has to be set to DNS Only, the grey cloud. The symptom people report is a Code 1004 error, and the fix is the toggle, not the value. Resend's Cloudflare integration publishes the records with the right setting for you.
You pasted the full hostname into the host field.
Most DNS editors append your zone to whatever you type, so pasting send.example.com produces send.example.com.example.com. The record exists, it looks
right in the editor, and it resolves at a name nobody will ever query.
Paste the label only, then confirm with a lookup at the name you
expect.
An MX priority collides. Resend's return-path MX is priority 10. If another MX record already sits on the same host at priority 10, resolve the conflict by bumping the other record to 20 or 30 so the priorities are distinct. This bites most often on apex setups, which is one more reason to use the send subdomain.
Trailing periods. The DKIM CNAME value ends in a dot,
as in <token>.dkim.amazonses.com., because it is a fully
qualified name. Some registrars, Gandi among them, require that
trailing dot and others strip or reject it. If the value in your zone
does not match the value in the dashboard character for character,
check the dot before you check anything else.
Propagation. The unglamorous answer. DNS changes are cached, and a zone with long TTLs can take up to roughly 72 hours to be visible everywhere. Resend keeps rechecking on its own. If a record resolves correctly from a public resolver and the status has not moved, waiting is the correct action.
Check the records yourself before you wait.
Before you file a support ticket, ask public DNS what it actually
returns. An empty result means the record is not published at the name
you think it is. On Windows, nslookup -type=TXT send.example.com asks the same
question.
# SPF on the send subdomain dig +short TXT send.example.com # Return-path MX (the value carries the region) dig +short MX send.example.com # One of the three DKIM CNAMEs (token from the dashboard) dig +short CNAME <token>._domainkey.send.example.com # DMARC, once you publish it dig +short TXT _dmarc.example.com
If the answers match the dashboard and the status is still pending, you are in the propagation case and there is nothing left to fix.
Sending and receiving verify separately.
A domain in Resend has capabilities, and there are two of them:
sending and receiving. They are verified independently, which is why
you can land on a status of partially_verified. That
status is not a broken state or a stuck state. It means one capability
passed its checks and the other did not, most often because you added
the inbound MX record later and it has not been detected
yet, or because you only ever intended to send and never published the
inbound record at all.
If you do want to receive mail on the domain, that adds one more MX record on the host inbound at priority
10, and it comes with its own set of behaviors around the email.received webhook. That is covered in the guide to receiving email with Resend
.
Once the domain reads verified, the interesting part is what happens to the mail. Connecting Resend to GetFluxly turns every delivery, bounce, open, and click into an event on the customer profile, without you building the webhook consumer yourself.
Resend domain verification, common questions answered.
How long does Resend domain verification take?
Usually a few minutes, but the honest answer is that it takes as long as your DNS provider takes to propagate. Resend rechecks the records on its own and flips the domain to verified as soon as it can read them in public DNS. Propagation can take up to about 72 hours on slow or heavily cached zones, so if the records are correct and the status has not moved after a few hours, the fix is to confirm the records resolve publicly rather than to delete and re-add the domain.
Why is my Resend domain stuck on pending?
Pending means Resend has not been able to read one or more of the records yet, and it is almost always a DNS problem rather than a Resend problem. The four causes that account for most cases are a Cloudflare record left on the orange cloud (proxied) instead of DNS only, the full hostname pasted into a host field that already appends your zone, an MX priority collision with an existing record on the same name, and simple propagation delay. Verify each record with dig against a public resolver before assuming anything else.
Does Resend require DMARC?
No. Resend verifies a domain on the SPF, DKIM, and MX records alone, so a missing DMARC record will not block you from sending. You should still publish one. Start with a monitoring-only policy at p=none plus an rua address so you can read alignment reports, then tighten to p=quarantine and eventually p=reject once you have confirmed every legitimate sender for the domain passes.
Can I use my root domain instead of a subdomain?
Yes, Resend can verify an apex domain, but the recommended setup is a dedicated sending subdomain such as send.example.com. The subdomain keeps your sending reputation separate from the reputation of your corporate mail, and it avoids the practical problem that the return-path MX record would otherwise have to live alongside the MX records your business mail provider already owns on the apex. If you send from the apex, a reputation problem in one stream follows the other.
Do Resend DNS records differ by region?
Only one value changes. Resend lets you pick a region when you add the domain, currently us-east-1, eu-west-1, sa-east-1, and ap-northeast-1, and the region appears inside the return-path MX value as feedback-smtp.<region>.amazonses.com. The SPF string, the DKIM CNAME pattern, and the optional tracking CNAME are identical across regions. Copy the MX value from the dashboard rather than assembling it yourself.