Your question
While upgrading to v16 it seems I lost some emails
how to merge the backup with the new running data directoriy?
linux, rocksdb, non-docker
There is no built-in feature in Stalwart to merge two separate data directories together. The only import/export tooling that exists (--export / --import) performs a full raw database dump-and-restore between backends, it does not merge on top of an existing populated database, and it must be run while the server is stopped.
To recover the lost emails, the practical approach is:
imapsync, or by using the WebUI/JMAP client to move messages across accounts.The export/import utility itself is explicitly documented as not a backup/merge tool: “it is not designed for regular backup and recovery tasks… it’s not a substitute for proper backup procedures.” See Database Migration | Stalwart for details on that utility’s actual scope.
This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong.
Before you try to merge anything, I would find out whether the mail is gone at all. The v0.16 migration does not touch stored mail: message bodies, mailboxes, calendars and files stay exactly where they were on disk, and the layout is unchanged.
The first v0.16 start resets a handful of state that reads as missing mail with nothing gone. The full-text index is dropped, so search comes back empty until it is rebuilt. Per-account disk quotas reset to zero and need the “Recalculate disk quotas” task. And directory records are recreated from the migration’s export file, so if an account was recreated by hand instead, it gets a new identity and its old mail is still on disk but attached to nobody. That last one is the usual culprit when whole mailboxes appear empty. Also confirm the datastore path in your new config.json points at the same RocksDB directory as before and not a fresh one.
Merging two RocksDB directories is not something the server can do. The --import path is a raw subspace dump meant for moving between backends, and it refuses outright when the target already holds data in those key ranges, by design.
If it does turn out you have two separate stores with different mail in each, the way across is Vandelay: bring the backup up as a second isolated instance with its own config and no public listeners, then vandelay import jmap from it into an archive per account and vandelay export that archive into the live server. Export is additive and rematches what is already there, so running it twice does not duplicate anything. Do not pass --prune, which is the destructive variant, and use --dry-run first.
What is missing, specifically? Whole accounts, whole folders, or only search results? The answer points at a different one of the three above.
I am also running into this issue. I believe the data to still be there, but the accounts to not be attached to them.
I think this is because I made a mistake following the upgrade guide and had to re-do a few steps.
Is there a way to recover this data by re-linking it? I only have 4 user accounts, so some manual action should not be an issue.
I think this issue to be related to this issue? I would prefer not to get the login information for my (4) users in order to restore their account.
Thank you for your support.
Kind regards,
Dexterdy
@dexterdy you won’t need anyone’s password. export.json carries each user’s v0.15 password hash and the server stores it as is, so the accounts come back with their existing logins.
What decides whether the mail is attached is the account id. Mail is stored under the numeric account id, and the migration recreates each account with its old id through the restore- keys in export.json. Those keys only take effect while the server runs in recovery mode. If apply was run again against a normally started server, or the users were created by hand in the web UI, they got new ids, and the old mail is still sitting under the old ones.
Stop the server and copy the data directory before anything else. Then start it with STALWART_RECOVERY_MODE=1 and STALWART_RECOVERY_ADMIN=admin:, point the CLI at http://127.0.0.1:8080 and run:
stalwart-cli query Account --fields id,name
Compare the ids with the restore- keys in export.json. The CLI prints ids base32-encoded; below 32 that’s a single character from abcdefghijklmnopqrstuvwxyz792013, so 0 is a, 1 is b and 12 is m. If they match, the accounts are attached and it’s the search index or the quota reset from my earlier reply. If they don’t, the fix is to rename the wrong accounts out of the way and apply each user’s block from export.json again, with its restore- key, while still in recovery mode (stalwart/UPGRADING/v0_16.md at main · stalwartlabs/stalwart · GitHub). Post the output and the keys first, though, because a hand-made account can end up holding another user’s old id, and that changes the order of the steps.
Don’t delete any account in the meantime. On the community edition that erases its mail immediately. Which steps did you redo, and was any account deleted at some point?
The ID’s line up, so it must be the quotas or the search. I am looking for the UI option "Recalculate disk quotas". I can find the create new task option, and from there I can select account maintenance and the recalculate disk quota for this user account, but that only scans a single selected account?
With only a few users it is not a problem to just schedule this task 4 times, but is this the correct option that is being referred to in the documentation?
Thank you for your help
@dexterdy yes, that’s the right task, and running it four times is fine. The guide’s name for it is wrong, though. The one-shot version is under Store maintenance as “Reset all user quotas”, and despite the label it doesn’t zero anything: it queues that same per-account recalculation for every account, spread over about five minutes. I’ll get the guide’s wording fixed.
If it’s search that comes back empty, Store maintenance also has “Reindex all accounts’ data for search”, which fans out per account the same way. A wrong quota on its own never hides mail. So if folders or messages are still missing after both, tell me what exactly is missing and where you’re looking, web UI or an IMAP client.
Okay, I have done both, but the emails are still not there.
I am using the nextcloud mail app, which I believe is just IMAP. The mail app on macos has the same result.
All mails from before the migration are missing. Everything in the inbox is gone, and mail folders are also gone. As if the account was brand new, except for the fact that we can still receive email and use the same credentials.
As for the steps that I repeated, I believe it was step 2 (in option B docker deployment) that I accidentally skipped so I am pretty sure that I started the migration from a scratch.
Skipping step 2 explains all of it. Without that copy, docker run -v stalwart-data:... created a new empty volume, the server started a fresh database in it, and apply recreated your accounts with their old IDs, so the IDs match and the logins work while every mailbox is empty. Your mail never left the old v0.15 data directory, and since step 2 only copies from it, it should still be there untouched. Is it?
If it does, redo the migration into a new volume. Stop the container and leave stalwart-data alone, create a second volume, run step 2’s copy into it, then repeat steps 4 to 7 against it with the same config.json and export.json and check that the old mail appears. If mail has arrived since the upgrade that you need to keep, bring the current volume up as a separate instance with no public ports afterwards and move it across with Vandelay as described earlier in this thread (--dry-run first, no --prune). If nothing important came in, skip that part.