Custom return path: the envelope address that makes SPF align and bounces come home
Published Updated 10 min readBy the Rasket team

What the return path is
A custom return path is a return path on a subdomain of your own domain, rather than on the sending service’s. To see why that matters, start with what the return path is. When one mail server hands a message to another, it does not begin with the message. It begins with an envelope: a MAIL FROM command naming the address any failure notice should go to, then RCPT TO for each recipient, and only then the message itself. That MAIL FROM address is the return path. RFC 5321 calls it the reverse-path; people also call it the envelope sender, the bounce address, or the mail from domain when they mean the part after the @.
S: 220 mx.example.com ESMTPC: EHLO out.mail.example.netS: 250 mx.example.comC: MAIL FROM:<bounce+7f3a9c@send.acme.example>S: 250 2.1.0 OKC: RCPT TO:<ronald.williams@example.com>S: 250 2.1.5 OKC: DATAS: 354 Go aheadC: From: Acme <orders@acme.example>C: To: ronald.williams@example.comC: Subject: Your order 1042C:C: Thanks for your order.C: .S: 250 2.0.0 AcceptedNotice that the envelope and the message disagree about who the mail is from. The envelope says bounce+7f3a9c@send.acme.example; the message says orders@acme.example. That is not a mistake. The envelope address exists for the machines: it is unique per message, so a bounce that comes back to it can be matched to the send that caused it. The header address exists for the reader.
When the receiving server accepts the message for final delivery, RFC 5321 section 4.4 tells it to write the envelope address into a Return-Path header at the top of the message. That header is how you can see the return path in a delivered message: it is written by the receiver, not the sender, which is also why the API refuses a Return-Path header in a request body.
Return-Path: <bounce+7f3a9c@send.acme.example>Received: from out.mail.example.net (out.mail.example.net [192.0.2.10]) by mx.example.com with ESMTPS; Wed, 16 Sep 2026 10:14:02 +0000Authentication-Results: mx.example.com; spf=pass smtp.mailfrom=send.acme.example; dkim=pass header.d=acme.example header.s=rasket; dmarc=pass header.from=acme.exampleFrom: Acme <orders@acme.example>To: ronald.williams@example.comSubject: Your order 1042What happens when the message cannot be delivered
If ronald.williams@example.com no longer exists, the receiving server either refuses it during the conversation, with a 550 reply the sending server sees immediately, or accepts it and later generates a delivery status notification. That notification is an ordinary email, and it is addressed to the return path. The unique local part, bounce+7f3a9c in the example, is how the server that receives the notification knows which send it belongs to without parsing the human-readable text. From there it becomes an email.bounced event and, for a hard bounce, a suppression; the bounce post covers what happens next. None of that works unless the return-path domain can receive mail, which is the first of the two records below.
Header From vs envelope From
Two addresses, two jobs. The confusion between them is behind most questions about why SPF passed and DMARC failed, so it is worth laying them side by side.
| Header From | Envelope From (return path) | |
|---|---|---|
| Set by | The application, in the message: the from field of the send request. | The sending server, in the SMTP conversation, before the message is sent. |
| Seen by | The reader, in every mail client. | Servers only. A reader finds it in the Return-Path header if they look. |
| Checked by | DMARC, which uses its domain as the one everything must align with. | SPF, which looks up the SPF record of its domain and checks the connecting server. |
| Carried in | The From header, part of the signed message. | The MAIL FROM command, then the Return-Path header the receiver writes. |
| Where failures go | Nowhere. Replies go to it, or to Reply-To if set. | Bounces and delivery failures, as messages sent to this address. |
| Best for | Telling the reader who wrote to them, on the domain they know you by. | Telling servers where failures go and which SPF record to read, on a subdomain built for that. |
The row that decides everything is “Checked by”. SPF never looks at the From header. It takes the domain from the return path, fetches that domain’s SPF record, and asks whether the connecting server is listed. DMARC then asks a second question SPF cannot: does the domain that passed have anything to do with the domain the reader sees? RFC 7489 section 3.1 calls that identifier alignment, and it is the whole reason a return path on your subdomain is worth having.
Why a custom return path on your own subdomain
A sending service has to put something in MAIL FROM. The easy choice is an address on its own domain: one SPF record for every customer, bounces flowing back to one place, nothing for the customer to configure. It works, and it passes SPF. The trouble is what it passes SPF for.
SPF alignment under DMARC
With a shared return path, the SPF check passes for the provider’s domain. Your From header says acme.example. DMARC compares the two, finds no relationship, and records SPF as unaligned. The message can still pass DMARC on DKIM, and usually does, but it now rests on one leg. Any hop that breaks the signature, such as a mailing list that adds a footer, leaves it with nothing. With the return path at send.acme.example, SPF passes for a subdomain of the From domain, which aligns under DMARC’s default relaxed mode, and the message has two independent ways to pass.
Your own bounce namespace
A bounce is a message. It is delivered to the return-path address, so whoever runs the mail exchanger for that domain gets to read it. On a shared return path the provider reads every customer’s bounces from one mailbox and sorts them by the unique local part. On your subdomain the same thing happens, but the address the bounce was sent to is yours, the DNS that routed it is yours, and if you ever move providers the addresses still resolve to something you control while old bounces trickle in.
Brand, and a reputation of your own
Receivers keep reputation per domain as well as per IP address, and the return-path domain is one of the identities they track. A shared return path pools your bounce behaviour with every other customer’s. A custom one keeps the SPF and bounce history of send.acme.example attached to you: good if you send carefully, and fair either way. Some anti-spam filters also compare the two domains and treat a mismatch as a weak signal. Aligned domains remove that from the scoring.
If DKIM already aligns, do you need it?
Strictly, no: DMARC passes when either leg aligns, and a DKIM signature on your domain is enough on a good day. The case for the second leg is the bad day. A forwarder that re-encodes the body, a security gateway that rewrites links, a list that adds a footer: each breaks the signature, and a message with only DKIM to lean on then fails DMARC at a domain that has moved to quarantine or reject. SPF alignment does not survive forwarding either, so the two legs fail in different places, which is exactly why having both is worth the two records.
Reading it in the headers
The Authentication-Results header in the delivered message above is where a receiver writes its verdicts, and it names the domain each check was made for: smtp.mailfrom=send.acme.example for SPF, header.d=acme.example for DKIM, header.from=acme.example for DMARC. Send yourself a message and read those three values. If the SPF domain belongs to your provider rather than to you, SPF is passing but not aligning, and that is the gap a custom return path closes.
What it does not do
A custom return path does not change what readers see, does not replace DKIM, and does not make a bad list deliverable. It makes SPF count towards DMARC and keeps bounce routing inside your own domain. Both are worth having; neither is a substitute for a signature that aligns and a suppression list that is honoured.
The records at the return-path label
Two DNS records at the return-path subdomain make it work. Both are generated for you when you add a domain, so the job is publishing them, not composing them.
- An MX record at the label. This names the mail exchangers that accept mail for
send.acme.example, which is where bounce notices are delivered. Many receivers refuse aMAIL FROMwhose domain cannot receive mail, so the record is a deliverability requirement as well as a routing one. It points at the servers that read bounces on your behalf and turn them into theemail.bouncedevents and suppressions you see. - An SPF TXT record at the label. A
v=spf1record scoped to the subdomain, authorising the servers that send your mail. Because SPF looks up the return-path domain, this record is the one that gets evaluated, not the one at your apex.
That second point deserves a sentence of its own. Your domain’s root SPF record, the one at acme.example that covers your office mail and whatever else sends with a bare-domain return path, is untouched. You do not add an include to it, you do not spend any of its ten-lookup budget, and a mistake in one record cannot break the other. RFC 7208 evaluates exactly one record, at exactly the return-path domain, and a subdomain has its own.
You can check both from a terminal once they are published: dig MX send.acme.example should answer with at least one exchanger, and dig TXT send.acme.example with a single string beginning v=spf1. If either comes back empty an hour after you saved it, the usual cause is the record name: a panel that wanted send and was given the full hostname has published it at the wrong label.
Why a subdomain rather than the apex? Because the apex already has both records, and they do other work. The MX at acme.example points at your mailbox provider, and routing every bounce there would deliver machine-generated failure notices into a human inbox. The SPF record at the apex lists what sends your office mail. Giving the return path its own label gives it its own MX and its own SPF, scoped to the one job, and the SPF entry in the glossary explains why keeping that record short matters.
The values themselves are printed in the dashboard and returned by the API for your domain, and nowhere else, because they name the infrastructure behind them. Copy them from there. If the label is a subdomain of a subdomain, say send.mail.acme.example because you added mail.acme.example, most DNS panels want the record name relative to the zone, so send.mail rather than the full name; the verification walkthrough covers that and the other panel habits that trip people up.
How Rasket sets it
Every sending domain gets a return path at the send label of that domain by default. Add acme.example and the return path is send.acme.example; add mail.acme.example and it is send.mail.acme.example. The DKIM key is published under the rasket selector on the domain itself, so DKIM aligns with the From domain exactly and SPF aligns with it in relaxed mode. Both legs of DMARC are yours from the first message.
If send is taken, or you prefer another name, custom_return_path on POST /domains picks a different label. It is a label, not a hostname: pass bounce and the return path becomes bounce.acme.example.
curl -X POST https://api.rasket.com/domains \ -H "Authorization: Bearer $RASKET_API_KEY" \ -H "User-Agent: acme-billing/1.0" \ -H "Content-Type: application/json" \ -d '{ "name": "acme.example", "custom_return_path": "bounce" }'The response lists every record to publish, including the MX and the SPF TXT at the label you chose. Nothing sends until the domain verifies: publish the records, call POST /domains/{id}/verify, and check each record’s status in the response. Records are re-checked on a schedule afterwards, so a return-path record that disappears during a DNS migration is reported rather than silently failing SPF. The domains reference documents every field, and the domains page shows what the record set looks like.
The label is worth choosing once. A message carries the return path it was sent with, so if you ever move to another label, leave the old records in place until the last bounce addressed to the old one has arrived. For most domains the right answer is to leave it at send and spend the attention on the DMARC record instead.
Frequently asked questions
Is the return path the same as the Reply-To address?
No. Reply-To is a message header that tells a mail client where a human reply should go, and readers can see it. The return path is set in the SMTP envelope before the message is sent, is invisible to readers, and is where servers send bounces and delivery failures. A message can carry both, pointing at different domains, and usually does.
Do I still need a custom return path if DKIM already aligns?
DMARC passes when either SPF or DKIM aligns, so a domain with an aligned DKIM signature passes on a good day. The custom return path gives you the second leg for the bad day: a forwarder or gateway that alters the body breaks DKIM, and a message with only one aligned leg then fails at any domain enforcing quarantine or reject. Two legs that fail in different places is the point.
Does the return path change what the recipient sees?
No. The recipient sees the From header, which you set in the send request, and never the envelope address unless they open the raw headers and look for Return-Path. The custom return path exists for receiving servers, which use it for the SPF lookup and for routing bounces, and for the systems that turn those bounces into events.
Do I need to change my domain's existing SPF record?
No. SPF is evaluated for the return-path domain, so the record that matters lives at the subdomain the return path uses, and the one at your apex keeps serving whatever sends with a bare-domain envelope. You add nothing to it, its ten-lookup budget is untouched, and a mistake in either record cannot break the other.
Can I use a label other than send?
Yes. Pass custom_return_path when you add the domain with POST /domains, giving a label rather than a hostname: bounce makes the return path bounce.acme.example. The records are generated for whichever label you choose, and the domain still has to verify before anything sends. Most domains have no reason to change it, so leaving the default is a fine answer.
Sources
- RFC 5321: Simple Mail Transfer Protocol, section 4.4 (Trace Information and the Return-Path) — IETF, read 2026-09-16
- RFC 7208: Sender Policy Framework (SPF) for Authorizing Use of Domains in Email — IETF, read 2026-09-16
- RFC 7489: Domain-based Message Authentication, Reporting, and Conformance (DMARC), section 3.1 (Identifier Alignment) — IETF, read 2026-09-16
Related
- Custom return path (MAIL FROM) — The return path, also called MAIL FROM or the envelope sender, is the address bounces come back to. It is set during the delivery conversation between servers…
- SPF — SPF is a TXT record listing which servers may send mail for a domain. A receiving server looks up the record for the return path domain and checks whether the…
- DMARC alignment — Alignment is the part of DMARC that asks whether the domain that passed authentication is the same one the reader sees. A DKIM signature or an SPF check can…
- Domains — Add a domain, publish the generated record set and send from it. A 2048-bit DKIM key per domain, a custom return path, and verification that runs on its own.
- DKIM, SPF and DMARC explained for developers — What SPF, DKIM and DMARC each prove, the records to publish, how alignment ties them together, and what the large mailbox providers now require of senders.