Issue Description
I’m reporting an issue encountered while upgrading my Stalwart server from v0.16.27 to v1.0.0.
Environment:
- OS: Linux (systemd installation)
- Source version: Stalwart 0.16.27
- Migration tool:
stalwart-migrate 1.0.0 - Database: RocksDB
- Blob storage: Local RocksDB
- Migration performed offline, with the original server stopped
Issue:
The stalwart-migrate prepare command failed with a registry.deserialization-error, preventing the migration from proceeding.
My Stalwart 0.16.27 installation had been functioning normally before the upgrade.
I compiled a modified version of the migration tool with additional diagnostic logging and scanned the registry.
The scan identified 21 unreadable entries out of 2,870, including:
LogMtaDeliveryScheduleMtaExtensionsMtaHookMtaOutboundStrategyMtaStageAuthMtaStageConnectOidcProviderReportSettingsWebHook
I confirmed that the registry deserialization source files bundled with the migrator match those from Stalwart v0.16.27.
Workaround:
I modified crates/source-v016/src/adapter/registry.rs to skip entries that fail deserialization rather than aborting the migration.
With this modification, the migration completed successfully:
- 3,630 emails migrated
- 1 account migrated
- 2,698 blobs copied
- Full verification: 0 mismatches, 0 unexplained differences
The skipped registry entries were not migrated, so some configuration settings may still need manual restoration.
Suggestion:
It would be useful if stalwart-migrate could handle unreadable legacy registry entries more gracefully, for example by allowing users to skip them with an explicit warning instead of aborting the entire migration.
Expected Behavior
stalwart-migrate prepare should successfully read and convert the registry from Stalwart 0.16.27 to 1.0.
If a legacy registry entry cannot be deserialized, the migration tool should report its type and ID and ideally allow skipping it with a warning
Actual Behavior
stalwart-migrate 1.0.0 fails during prepare with registry.deserialization-error.
I identified 21 unreadable registry entries out of 2,870, including Log, MtaDeliverySchedule, MtaHook, MtaExtensions, MtaOutboundStrategy, OidcProvider and others.
I modified crates/source-v016/src/adapter/registry.rs to skip unreadable entries.
After this modification, the migration completed successfully:
- 3,630 emails migrated
- 1 account migrated
- Full verification: 0 mismatches
One security concern: the original error message includes the complete Base64-encoded registry value, which in my case contained a PEM private key.
Reproduction Steps
- Install Stalwart 0.16.27 with RocksDB on Linux.
- Install
stalwart-migrate 1.0.0. - Execute:
stalwart-migrate prepare --source /etc/stalwart/config.json --state /var/lib/stalwart-migrate - Observe
registry.deserialization-error. - The same issue occurs with an offline copy of the RocksDB database.
- Patching the registry iterator to skip entries that fail deserialization allows the migration to complete.
The issue depends on the stored registry entries, so it may not reproduce on a fresh installation.
Relevant Log Output
ERROR stalwart_migrate: command failed
error=account error: Registry deserialization error
(registry.deserialization-error)
causedBy = vendor/v016/crates/store/src/registry/mod.rs:96
value = [REDACTED: contains PEM private key]
Diagnostic:
REGISTRY DECODE FAILED: type=Log, id=20080258862541
REGISTRY DECODE FAILED: type=MtaDeliverySchedule, id=20080258862541
Registry scan:
21 errors, 2870 entries checked
After applying the skip patch:
run finished status=ok
verify: 1 accounts checked, 0 mismatches, 0 unexplained (ok)
Stalwart Version
v1.x
Installation Method
Binary (Linux)
Database Backend
RocksDB
Blob Storage
RocksDB
Search Engine
Internal
Directory Backend
Internal
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