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.