Issue Description
An account can’t send anymore once it has 500 EmailSubmission records. EmailSubmission/set then fails with overQuota until someone deletes records or raises the limit.
Expected Behavior
old submissions are purged after expungeSubmissionsAfter, and a client that never destroys its EmailSubmission records can keep sending.
Actual Behavior
the records stay forever and count toward x:Email.maxSubmissions (500 by default). Once an account reaches it, every new submission is refused:
"notCreated": {"s": {"type": "overQuota", "description": "There are too many email submissions, please delete some before adding a new one."}}
The Email/set in the same request still creates the draft. Cleaning up from the client side is hard too: EmailSubmission/query and EmailSubmission/get with ids: null only return records from the last 3 days, so the older ones can’t be found but still count.
Reproduction Steps
1 As admin, give a user a low limit: x:Account/set with “quotas/maxEmailSubmissions”: 2.
2 As that user, send three messages (Email/set + EmailSubmission/set).
3 The third EmailSubmission/set fails with overQuota. Destroying one submission, or removing the override, makes the next send work again.
Without the override the same happens at the 501st record. I didn’t run that, it’s the same code.
The purge (found in the code, didn’t run it):
1 Set x:DataRetention expungeSubmissionsAfter to 60000 and restart.
2 Send two messages and note the submission ids.
3 Wait a minute, then run the account purge: x:Task/set create {“@type”: “AccountMaintenance”, “accountId”: “”, “maintenanceType”: “purge”}.
4 EmailSubmission/get with both ids still returns them.
Stalwart Version
v0.16.x
Installation Method
Built from source
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
Additional Context
in crates/email/src/message/delete.rs, purge_email_submissions iterates from a key with Collection::EmailSubmission (line 236) to a key with Collection::Email (line 245). Both keys start with the account id and then the collection byte, and EmailSubmission (4) sorts after Email (0), so the range is empty and nothing is deleted. It came in with d5c5f12ad.
Even with the end key fixed, the purge only clears the metadata and index entry (lines 284-292). The archive stays and no change is logged, while destroy in jmap/src/submission/set.rs does both.
count_submissions (jmap/src/submission/set.rs, lines 78-111) counts every record regardless of age or status. For a limit it would probably make more sense to count only submissions that can still be undone.
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