Issue Description
The iMIP/iTIP inbound auto-add path requires is_sender_authenticated
to be true, which is hard-coded to require a strict
DmarcResult::Pass. Senders whose domain has no DMARC record published
— but whose messages still authenticate via DKIM (e.g. ordinary Google
Workspace tenants that only published Google’s recommended SPF and DKIM
but did not publish a DMARC TXT record) — are silently skipped by the
iTIP processor. The invitation is delivered to the inbox as a plain
message but never inserted into the recipient’s CalDAV calendar, even
with calendar.scheduling.inbound.auto-add = true.
This is stricter than how Gmail, Outlook, and most other mail providers
treat the same messages — they accept DKIM-pass as sufficient
authentication for iMIP auto-processing. As a result, Stalwart fails to
interoperate with a large slice of real-world Google Workspace senders
who follow Google’s default setup.
Source references for v0.15.5:
crates/smtp/src/inbound/data.rs:716—dmarc_passis computed
strictly:dmarc_result.is_some_and(|r| r == DmarcResult::Pass). No
other auth path sets the flag.crates/smtp/src/outbound/local.rs:45—sender_authenticatedis
then(FROM_UNAUTHENTICATED_DMARC | FROM_AUTHENTICATED) != 0.crates/email/src/message/ingest.rs:350— iTIP processor is gated on
is_sender_authenticated. The processor is skipped silently when
this is false; no log line is emitted indicating the iMIP part was
seen but rejected.crates/groupware/src/calendar/itip.rs:281—itip_auto_addonly
loosens the address-book check, not the upstream auth gate.
Expected Behavior
Either (a) calendar.scheduling.inbound.auto-add = true could relax
the DMARC requirement so that DKIM-pass is sufficient, matching
Gmail/Outlook behavior; or (b) a new, distinct knob is added — e.g.
calendar.scheduling.inbound.require-dmarc-pass = false /
inbound.accept-dkim-only = true — that an operator can opt in to.
The current auto-add documentation suggests it broadly relaxes the
inbound gate; the actual scope is narrower (address-book only) which
is surprising.
Additionally, when the iTIP path is skipped due to the auth gate, it
would be very helpful to emit an INFO-level log line so operators
can diagnose “why didn’t this invitation auto-add?” without having to
read the source.
Actual Behavior
iMIP invitation from a real Google Workspace tenant
(<user>@<workspace-domain>) — DKIM passes for both google.com and
<workspace-domain>-fi.<date>.gappssmtp.com, but DMARC fails with
result = No DMARC record (dmarc.none) because the tenant has not
manually published _dmarc. Stalwart delivers the message to the
inbox and does nothing else. The recipient’s /dav/cal/<user>/default/
is not touched. No log line indicates that iTIP processing was even
considered. The recipient’s native CalDAV client (Fantastical, Apple
Calendar, Thunderbird Lightning) shows no RSVP UI because there is no
calendar object to act on.
Even setting calendar.scheduling.inbound.auto-add = true has no
effect on this path.
Reproduction Steps
- Fresh Stalwart v0.15.5 instance with
calendar.scheduling.inbound.auto-add = trueinconfig.toml. - Verify the setting is effective:
curl -u admin:$PW http://127.0.0.1:8080/api/settings/list?prefix=calendar.scheduling
returnsinbound.auto-add: true. - Send a Google Calendar invitation from a Workspace tenant whose
primary domain has no_dmarcTXT record. (Most Workspace tenants
who followed only Google’s default DNS setup wizard are in this
state — Google does not publish_dmarcby default.) - Observe in the Stalwart log:
DKIM verification passedand
DMARC check failed ... No DMARC record (dmarc.none). - Observe that the message is delivered to the inbox
(message-ingest.ham ... mailboxId = [0]) but no
ItipMessageReceivedevent is logged. - PROPFIND on
/dav/cal/<recipient>/default/confirms no new event
was inserted.
Relevant Log Output
2026-05-27T06:39:31Z INFO DKIM verification passed (smtp.dkim-pass) ... result = [DKIM verification passed (dkim.pass) { domain = "google.com" }, DKIM verification passed (dkim.pass) { domain = "<workspace>.gappssmtp.com" }]
2026-05-27T06:39:31Z INFO DMARC check failed (smtp.dmarc-fail) ... domain = "<workspace-domain>", policy = "none", result = No DMARC record (dmarc.none)
2026-05-27T06:39:31Z INFO Queued message for delivery ... from = "<user>@<workspace-domain>", to = ["<recipient>@<our-domain>"], size = 38415
2026-05-27T06:39:31Z INFO Message ingested (message-ingest.ham) ... accountId = 6, documentId = 8, mailboxId = [0]
# expected but missing: ItipMessageReceived / ItipMessageError event
Stalwart Version
v0.15.x
Installation Method
Docker
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
Additional Context
- Same domain works for the same recipient on Gmail/Outlook — those
servers’ iMIP processors do not require DMARC pass and accept
DKIM-pass as sufficient. - Reproduced both with the sender’s domain having no
_dmarcrecord
and verified manually that adding
_dmarc.<domain> TXT "v=DMARC1; p=none"to the sender’s DNS makes
the auto-add work end-to-end on the same Stalwart instance —
proving the gate is the only blocker, the rest of the pipeline is
healthy. - Use case: small business mail server, ~5 mailboxes, native CalDAV
(Fantastical, Apple Calendar) is the primary client. Auto-add is
the only practical path — manually opening.icsattachments and
replying via Roundcube is fine as a fallback but defeats the value
of running a CalDAV server. - We are willing to contribute a PR if the maintainers can agree on
the preferred config-knob name and scope.
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