Skip to content

Recovering deleted items

Users delete things by mistake, and often notice only after the item has gone from every folder. The deleted-item archive covers that case. It keeps the items that users have deleted for a set period, so that they can be restored after a mistake. This includes messages that have already been expunged from the Deleted Items or Junk folder.

The archive holds messages, files, calendar events, contact cards and Sieve scripts. It is kept on the server’s own stores, so it is lost together with them, and it is not a substitute for a backup.

The archive is off until a retention period is set. The period is set by archiveDeletedItemsFor on the DataRetention singleton, in the WebUI under Settings › Storage › Data Retention › Archiving, and is given in milliseconds. When the field is empty, which is the default, deleted items are removed at once and nothing is archived. Setting a duration is therefore what enables the archive.

The choice of period is a balance: a longer period gives users more time to notice a mistake, and keeps deleted items on the stores for longer. The following value keeps deleted items for 30 days:

{
"archiveDeletedItemsFor": 2592000000
}

Deleted accounts have a similar setting. archiveDeletedAccountsFor delays the deletion of the data of deleted accounts (Delete an account), so that an account can be restored during that period. Restore a deleted account describes how.

Each archived item is an ArchivedItem object of the account it belongs to. The object records two times: when the item was archived (archivedAt), and when it will be deleted permanently (archivedUntil).

Users and administrators reach the archive in different ways. Users see the archived items of their own account in the Account Manager, under Account › Archived Items. Administrators can reach the items of every account they manage.

To restore an item, set its status to requestRestore, either in the WebUI or with an x:ArchivedItem/set update. The server then creates a RestoreArchivedItem task, which puts the item back into the account (Tasks). The following update requests the restoration of the item with id e:

["x:ArchivedItem/set", {
"update": {
"e": {"status": "requestRestore"}
}
}, "0"]

Deleting an ArchivedItem works differently: it removes the item from the archive permanently.

Reading, changing and deleting archived items require the sysArchivedItemGet, sysArchivedItemQuery, sysArchivedItemUpdate and sysArchivedItemDestroy permissions. The default User role holds them for the user’s own items, which is what lets users recover their own mail.

A deleted account remains restorable until its data is deleted. Deleting an account does not remove its data at once. It schedules a DestroyAccount task that is due when the archiveDeletedAccountsFor period ends. Deleting that task before it runs restores the account.

The server then re-creates the account with its original id, name and domain, so its mailboxes, messages, calendars, contacts and files are available again. It also schedules a task that rebuilds the account’s share index.

The restoration is partial. The other fields of the account are not restored: credentials, group memberships and the remaining settings take their default values, and must be set again before the account is used.

The pending task is listed in the WebUI under Management › Tasks › Scheduled, Management › Tasks › Failed, and can also be found with the CLI. The following commands list the pending account deletions, whose accountName identifies the account, and delete the task with id b:

Terminal window
stalwart-cli query Task --where @type=DestroyAccount
stalwart-cli delete Task --ids b

Two failures are possible. A task that is already running cannot be deleted, and the request fails with Task is currently being processed and cannot be destroyed. The restoration itself fails with Account recovery failed when the account cannot be re-created, for example because another account now has its name.

Deleting a DestroyAccount task requires the taskDestroyAccount permission.