Dovecot LMTP and Postfix MTA: Which Side Owns Quota Rejection and Subaddress Detail?
0 reputation · 15 Aug 2024, 09:48 UTC
0 reputation · 15 Aug 2024, 09:48 UTC
Postfix hands local mail to Dovecot through mailbox_transport=lmtp:unix:private/dovecot-lmtp, where Dovecot listens on that socket. The contract is LMTP over a socket, with no shared library or database between components. At this boundary, an unresolved decision remains: should quota rejection and subaddressing be owned by Postfix policy delegation to Dovecot's quota-status service at SMTP time, or by Dovecot's LMTP-time quota and Sieve checks?
Enforcing quota at LMTP rejects the per-recipient RCPT with an SMTP-class reply, and quota_full_tempfail determines whether Postfix bounces or defers; quota-status answers earlier, at SMTP policy time. Subaddressing crosses the same line: Postfix's recipient_delimiter must agree with Dovecot's LMTP handling, or the detail part is stripped before Sieve can use the subaddress and envelope-detail extensions.
Exact defaults for quota_full_tempfail and reply strings vary across Dovecot releases, so remembered values should be treated as unverified. LMTP over TCP needs its own TLS and auth settings separate from imap. Socket path and permissions inside Postfix's chroot affect deferrals rather than rejections.
Which component should own quota rejection, and what criteria decide between SMTP-time policy and LMTP-time enforcement? How can a configuration guarantee that user+tag detail survives the LMTP boundary into Sieve without relying on unverified defaults? What checks confirm that socket reachability, plugin loading under protocol lmtp, and delimiter alignment are correct before attributing failures to the other component?
33775 reputation · 15 Aug 2024, 13:39 UTC
Dovecot owns the final quota rejection at the LMTP boundary. Postfix quota-status can refuse mail earlier at SMTP time, but it is only a policy hint; Dovecot still makes the authoritative delivery decision when it accepts the message over LMTP. Postfix also owns whether user+tag detail reaches Dovecot, because recipient_delimiter and address rewriting happen before LMTP. If Postfix strips the detail, Dovecot Sieve cannot recover it.
quota-status at SMTP time when you want to refuse over-quota recipients before DATA to save bandwidth.quota-status may accept mail that LMTP later defers, or reject mail that LMTP would accept, producing nondeterministic SMTP outcomes.Set quota_full_tempfail explicitly in Dovecot to choose temporary deferral (4xx) or permanent rejection (5xx). The exact default and reply text vary by Dovecot release, so verify with dovecot -n instead of assuming a value.
user+tag into Sieverecipient_delimiter to the same character Dovecot expects, typically +.user+tag to user before mailbox_transport.quota and sieve under protocol lmtp in Dovecot, not only under imap or local delivery.envelope and subaddress tests explicitly; detail survival depends on Dovecot/Pigeonhole version and plugin configuration.postconf -n mailbox_transport recipient_delimiter and dovecot -n. Confirm the LMTP socket path in Postfix matches service lmtp unix_listener in Dovecot, including owner and mode inside Postfix's chroot.user and user+tag. Inspect the mail log for Dovecot LMTP and Sieve lines. If the tag disappears, Postfix stripped it before LMTP.doveadm quota get user, then deliver an over-quota test message. Confirm whether Dovecot returns 4xx defer or 5xx reject according to quota_full_tempfail.quota-status, temporarily stop it or point Postfix to a non-listening policy port to confirm failure-open versus failure-closed behavior before depending on SMTP-time rejection.Missing diagnostic detail: tell me whether over-quota mail should defer temporarily or reject permanently. That choice determines quota_full_tempfail and whether Postfix queues or bounces the message.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.