To obtain reliable quota enforcement on NFS-mounted mail directories, you must move away from filesystem-based metadata checks and implement a dictionary-based quota backend (dict quota). This shifts the source of truth from the remote filesystem's stat() calls to an external database or key-value store.
The Root Cause: NFS Metadata Caching
Dovecot's default maildir quota mechanism relies on filesystem metadata. On NFS, attribute caching (controlled by the mount's actimeo or noac settings) often results in stale data. When the quota plugin encounters inconsistent or delayed metadata, it may fail to trigger the limit, allowing mailboxes to grow unchecked without generating explicit error logs.
Recommended Solution: Dict Quota Backend
A dictionary backend stores quota usage in a database (SQL, Redis, etc.), updating the count during IMAP/LMTP operations rather than scanning the disk. This bypasses the NFS metadata dependency entirely.
Implementation Steps
- Define the Dictionary: Create a configuration file for your chosen backend (e.g.,
/etc/dovecot/dovecot-sql.conf.ext) to define how Dovecot connects to the database.
- Configure the Quota Backend: In
10-mail.conf, set the quota to use the dictionary proxy:
quota = dict:User quota::proxy::quota
- Set the Quota Rule: Define your limits as usual using
quota_rule. Dovecot will now check the database instead of the NFS directory size.
Diagnostics and Verification
Dovecot does not provide a specific "skipped check" signal for NFS. To verify that your new backend is functioning and to debug current behavior, use the following methods:
- Direct Query: Use
dovecotadm quota get -u <user> to verify the limit is being read from the dictionary rather than the filesystem.
- Debug Logging: Enable
mail_debug = yes in the Dovecot configuration. Search the logs for "quota" and "user" during a delivery attempt to confirm the plugin is actively evaluating the limit.
- Delivery Test: Send a message via LMTP that exceeds the limit; a successful implementation will return a quota-exceeded rejection immediately.
Assumptions and Limitations
This solution assumes you are using Dovecot 2.4.x or similar. Note that for dict quotas to remain accurate, all delivery agents (LMTP, local delivery, etc.) must be configured to update the dictionary. If external scripts modify the NFS maildir directly, the dictionary count will drift from the actual disk usage.
Missing Diagnostic Detail: Are you using a centralized MTA (like Postfix via LMTP) or local delivery? If using local delivery, additional configuration is required to ensure the dictionary is updated on every write.