This is a classic DMARC forwarding problem. When Stalwart’s Sieve redirect action forwards a message to an external address (e.g. Gmail), it sends the original message as-is but from your server’s IP. Since the From: header still says @yashworldproducts.in and your server’s IP is not in that domain’s SPF record, and there’s no aligned DKIM pass from their domain, DMARC rejects it.
Here’s what’s actually happening and how to fix it:
Why DMARC rejects forwarded mail
When you redirect a message, your Stalwart server re-injects it to the external recipient. The recipient’s mail server (Gmail) sees:
- From:
[email protected] (original sender’s domain)
- Sending IP: your server (not authorized by
yashworldproducts.in)
- Result: SPF fails, DKIM may be broken or missing for that domain → DMARC
p=reject fires
This is a fundamental DMARC/forwarding compatibility issue, not a Stalwart bug. The standard solution is SRS (Sender Rewriting Scheme) - rewriting the envelope MAIL FROM to your own domain so SPF passes for your domain instead.
Solution: Rewrite the envelope sender (SRS-style)
In Stalwart, you can rewrite the envelope.from in a Sieve script at the MAIL FROM or DATA stage. This makes your server the accountable sender for SPF purposes.
Here is the pattern using a system Sieve script hooked to the DATA stage:
require ["variables", "envelope", "editheader"];
# Rewrite envelope.from to your domain to pass SPF on forwarded mail
if envelope :domain :is "from" "yashworldproducts.in" {
set "envelope.from" "[email protected]";
}
But more practically, for a general forwarding rule you want to rewrite the return path to your own domain for all forwarded messages. The Sieve envelope extension lets you do set "envelope.from" "..." to replace it.
Forward without copy (redirect only)
require ["redirect"];
redirect "[email protected]";
# No "keep" = original is NOT kept locally
Forward with copy (redirect + keep local)
require ["redirect", "copy"];
redirect :copy "[email protected]";
# :copy means the original is ALSO delivered locally (implicit keep)
The redirect :copy action (RFC 3894) sends a copy to the external address while still delivering to the original mailbox. Without :copy, the message goes only to the redirected address.
The critical fix: rewrite envelope.from before redirecting
Put together, a user-level Sieve script that forwards with copy AND fixes DMARC looks like:
require ["copy", "redirect", "variables", "envelope"];
# Fix envelope sender so SPF passes from your server
set "envelope.from" "[email protected]";
# Forward with copy (keeps in local inbox too)
redirect :copy "[email protected]";
For forward without copy:
require ["redirect", "variables", "envelope"];
set "envelope.from" "[email protected]";
redirect "[email protected]";
You can manage your personal Sieve scripts via the WebUI, ManageSieve, or JMAP. System-level scripts that apply server-wide are configured under Settings > Sieve > System Scripts in the WebUI.
Relevant docs:
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.