Split Delivery - Loop

Your question

I’ve got a split delivery setup like is quite common - Google workspace infront, a few Gmail mailboxes and then forwarding unknown addresses to Stalwart via Default routing. I have relay enabled for the domain in stalwart and the MTA STS configured for using Google relay for outbound messages.

The problem I’ve got is that if an email is sent to a address that does not exist in Google nor in Stalwart, it ends up in a loop of bouncing between each other. I would like to be able to configure stalwart so that it can determine if the email is coming from Google, and if the mailbox doesn’t exist, reject it. But I don’t seem to be able to find a way to do this. Any ideas?

You do not need to detect that the mail is coming from Google. What you want is for Stalwart to reject unknown recipients at RCPT time, which is what it does by default. The loop comes from relaying being enabled on the domain: with that on, a recipient that does not resolve to a local account is accepted and relayed onward instead of being rejected, and since your outbound goes back out through Google, round it goes.

Turn allowRelaying off on the Domain object for that domain. Unknown recipients then get a 550 5.1.2 Mailbox does not exist. at RCPT, Google emits a single bounce to the original sender, and that is the end of it. Note this is the flag on the Domain object, not the one on the RCPT stage; the latter governs unknown domains and should stay at its default of authenticated sessions only.

Worth also checking there is no catch-all address set on that domain, since a catch-all would swallow the unknown recipients rather than rejecting them and you would see the same symptom for a different reason. Docs: stalw.art/docs/mta/inbound/rcpt

Thanks for your reply!

Will disabling allowRelaying not mean that any mail from mailboxes inside Stalwart for a google Workspace mailbox will be rejected?

Not really, my previous answer was wrong on that point. The relay flag is evaluated in the recipient resolver, which has no visibility of whether the session is authenticated, so turning it off would reject your own users writing to Google-hosted addresses in that domain with the same 550 5.1.2. The authenticated-sessions-only setting I mentioned governs unknown domains, and a domain you host locally never reaches that check, so it doesn’t rescue this.

So leave allowRelaying on: it’s what makes split delivery work in both directions, and there’s no way to get both behaviours out of that single flag. The loop has to be broken on the Google side instead. Scope the Default routing rule so it only applies to inbound external mail, unchecking the internal sending and receiving message types, and a message that Stalwart hands back is no longer routed onward to Stalwart again.

Check there’s no catch-all on the domain, since a catch-all is evaluated before the relay flag and would swallow unknown recipients regardless of it.