Available — Local Digital Products
HCA · Studio
TR — Contact ↗
Technical Note 06 · Server

Why your Dovecot quota is silently ignored

You write the rule, restart Dovecot, get no error — and mailboxes keep growing past the limit. The rule is not wrong. The file is never read.

Server
Dovecot / CyberPanel
Symptom
Quota ignored
Evidence
doveconf -n
Short answer

A stock Dovecot install splits its configuration into fragments under /etc/dovecot/conf.d/ and pulls them in with an !include conf.d/*.conf line in the main file. When CyberPanel writes its own dovecot.conf, it omits that include line. Everything you add under conf.d — quota included — is written to disk and never read. The fix is to put the quota block directly in the main dovecot.conf, or to add the include line deliberately. Verification is one command: doveconf -n prints the effective configuration, and if your quota lines are not in it, they are not in force.

The symptom

Everything looks done: a rule sits in /etc/dovecot/conf.d/90-quota.conf, the service has been restarted, the log is clean. And yet mailboxes sail past the limit and users are never warned.

At this point most people start questioning the syntax and spend an afternoon trying different quota_rule spellings. The syntax is fine. The file is simply never opened.

Root cause

Dovecot as shipped by most distributions splits configuration into fragments: 10-mail.conf, 10-auth.conf, 90-quota.conf and friends, all under /etc/dovecot/conf.d/. The only thing that makes them take effect is one line at the end of the main file:

!include conf.d/*.conf

When CyberPanel provisions the mail stack it generates /etc/dovecot/dovecot.conf from its own template. That template is a self-contained, single-file configuration and does not contain the include line. The conf.d directory still exists on disk, the files in it are readable, and Dovecot never looks at them.

This failure is silent by nature. Including a file that does not exist is an error. Not including a file that does exist is not an error — so nothing is ever logged.

Verify first

Before guessing, read the effective configuration. doveconf -n prints what Dovecot is actually using, with defaults stripped out:

# Anything quota-related that is actually in force
doveconf -n | grep -i quota

# Does the main file pull in conf.d at all?
grep -n 'include' /etc/dovecot/dovecot.conf

If the first command prints nothing, your quota configuration is not active. If the second shows no line mentioning conf.d, you have found the reason.

These two commands are worth turning into a habit for this whole class of problem: look at what the server reads, not at what the file says.

The fix

There are two routes. To avoid fighting the panel's generated structure, the preferred one is to append the quota block directly to the main file:

# at the end of /etc/dovecot/dovecot.conf

mail_plugins = $mail_plugins quota

plugin {
  quota = maildir:User quota
  quota_rule = *:storage=2G
  quota_rule2 = Trash:storage=+200M
  quota_grace = 10%
}

The quota_rule2 line grants Trash an allowance on top of the main quota. Without it, a user who has hit the limit cannot free space by deleting mail — deleted mail moves to Trash, which is inside the same quota, so usage never drops.

The other route is to restore the include. That returns Dovecot to standard behaviour, but carries the risk that a panel update regenerates the file and drops your line:

echo '!include conf.d/*.conf' >> /etc/dovecot/dovecot.conf

Whichever you choose, back the file up somewhere outside the web root before you touch it.

The IMAP side

Enforcing a quota and letting the client see the quota are two different things. For a mail client to show "80% full", the IMAP protocol needs its own plugin:

protocol imap {
  mail_plugins = $mail_plugins imap_quota
}

Without that line the quota still works — mail is rejected once the box is full — but the user gets no warning beforehand and discovers the limit through a bounce.

Reading the quota

After the change, restart the service and verify per user:

systemctl restart dovecot
doveconf -n | grep -i quota          # in force?
doveadm quota get -u user@example.com

That last command prints the user's current usage and limit as a table. If the limit column on the STORAGE row is empty, the quota is still not applied.

New mailboxes pick up the quota immediately. For existing ones Dovecot recalculates its usage counter on first access; if you are impatient, force it with doveadm quota recalc -u user@example.com.

Summary

The lesson here is not about quota syntax. It is about never assuming where configuration is read from. On panel-provisioned stacks the directory layout looks standard, but whether those files are actually included is a separate question. doveconf -n answers it, and so do nginx -T and apachectl -S for their servers: they show the running reality rather than the intention on disk.

Quick reference
Root cause
CyberPanel's dovecot.conf has no !include conf.d/*.conf
Effect
Everything under conf.d is silently ignored — no error raised
Diagnosis
doveconf -n | grep -i quota printing nothing means inactive
Fix
Put the quota block directly into the main dovecot.conf
Trash
Without quota_rule2 = Trash:storage=+200M users cannot delete to free space
Client warning
Without the imap_quota plugin users never see how full they are
Verify
doveadm quota get -u user@example.com
General rule
Look at what the server reads, not what the file says
Frequently Asked Questions

About Dovecot quotas.

Why is the setting I put in conf.d not working?

Because the /etc/dovecot/dovecot.conf that CyberPanel generates has no line including the conf.d directory. Dovecot reads only the main file. Your files are in the right place, their permissions are fine and their syntax is valid — they are simply never opened. You can confirm this in seconds with doveconf -n.

The quota applies, but users cannot free space by deleting mail. Why?

Deleted mail is moved to Trash, and Trash sits inside the same quota, so usage does not drop. Give Trash an allowance on top of the main quota with a rule such as quota_rule2 = Trash:storage=+200M. Alternatively, configure automatic expiry for the Trash folder.

Does a quota change apply to existing mailboxes?

Yes, but Dovecot updates the usage counter lazily and recalculates on first access to the mailbox. To see it immediately, run doveadm quota recalc -u user@example.com. Newly created mailboxes have no such delay.

Is adding the include line safe?

Technically yes — it restores Dovecot's standard behaviour. The risk is that a panel update regenerates dovecot.conf from its template, your line disappears and the quota silently stops applying. Writing the quota block directly into the main file, and backing up the change, is more durable.

Availability and Quotes

Have an idea?
Half a sentence is enough.