Issue Description
When a message bounces during the outbound SMTP connection, the returned message is discarded if the recipient is not found (VERP), even if there is a catchall set for the sending domain.
Expected Behavior
If there is a catchall set, it should be honoured on both regular and bounce paths.
Actual Behavior
There are two separate recipient-resolution paths and only one of them honors catch-all.
Inbound SMTP RCPT path — crates/common/src/network/mta.rs, rcpt_resolve(). Catch-all is applied unconditionally for an unresolved recipient:
rust// Catch-all resolution
if let Some(catch_all) = &domain.catch_all {
return Ok(RcptResolution::Rewrite(catch_all.to_string()));
}
The RCPT handler (crates/smtp/src/inbound/rcpt.rs) then rewrites the envelope recipient to the catch-all address before the message is queued. That’s why ordinary inbound mail to unknown recipients works.
Local delivery path — crates/email/src/message/delivery.rs:122:
rustlet account_id = match self.account_id_from_email(&rcpt.address, false).await {
Ok(Some(account_id)) => account_id,
Ok(None) => {
result.status.push(LocalDeliveryStatus::PermanentFailure {
code: [5, 5, 0], reason: “Mailbox not found.”.into(),
});
continue;
}
Reproduction Steps
Any mailing list software operating behind Stalwart would use VERP, I am using mlmmj. Reproducible by sending a message with MAIL FROM set to a VERP address.
Relevant Log Output
queueId = 308881299387452928, queueName = “local”, from = “<>”, to = [“test-94q8e5k+bounces-9-{REMOVED}”], size = 3300, total = 1, to = [“<test-94q8e5k+bounces-9-{REMOVED} (host ‘localhost’ rejected command ‘RCPT TO:<test-94q8e5k+bounces-9-{REMOVED}>’ with code 550 (5.5.0) ‘Mailbox not found.’)\r\n”]
Stalwart Version
v0.16.x
Installation Method
Binary (Linux)
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
I have reviewed the documentation and FAQ and confirm that my issue is NOT addressed there.
on
I have searched this support forum (open and closed topics) and confirm this is not a duplicate.
on
I understand that topics in this category are triaged by a bot first but a human reply will follow up. If I’d prefer a human-only reply, I’ll add the no-ai tag to my topic.
on