# Stalwart-migrate 1.0.0: Registry deserialization errors during v0.16.27 upgrade

**URL:** https://support.stalw.art/t/stalwart-migrate-1-0-0-registry-deserialization-errors-during-v0-16-27-upgrade/2045
**Category:** Issues
**Created:** [October 26, 2026, 11:06pm UTC](https://support.stalw.art/t/stalwart-migrate-1-0-0-registry-deserialization-errors-during-v0-16-27-upgrade/2045 "2026-10-26T23:06:48Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Simon\_FONTENEAU](https://support.stalw.art/user_avatar/support.stalw.art/simon_fonteneau/32/1166_2.png) [@Simon\_FONTENEAU](https://support.stalw.art/u/Simon_FONTENEAU)
#### Post date: [October 26, 2026, 11:06pm UTC](https://support.stalw.art/t/stalwart-migrate-1-0-0-registry-deserialization-errors-during-v0-16-27-upgrade/2045/1 "2026-10-26T23:06:48Z")

</div>

### 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:

- `Log`
- `MtaDeliverySchedule`
- `MtaExtensions`
- `MtaHook`
- `MtaOutboundStrategy`
- `MtaStageAuth`
- `MtaStageConnect`
- `OidcProvider`
- `ReportSettings`
- `WebHook`

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

1. Install Stalwart 0.16.27 with RocksDB on Linux.
2. Install `stalwart-migrate 1.0.0`.
3. Execute:

```auto
stalwart-migrate prepare --source /etc/stalwart/config.json --state /var/lib/stalwart-migrate

```

4. Observe `registry.deserialization-error`.
5. The same issue occurs with an offline copy of the RocksDB database.
6. 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

```plaintext
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

---

<div class="post-metadata">

### Author: ![helpbot](https://support.stalw.art/user_avatar/support.stalw.art/helpbot/32/13_2.png) [@helpbot](https://support.stalw.art/u/helpbot)
#### Post date: [October 26, 2026, 11:06pm UTC](https://support.stalw.art/t/stalwart-migrate-1-0-0-registry-deserialization-errors-during-v0-16-27-upgrade/2045/2 "2026-10-26T23:06:59Z")

</div>

The docs don’t describe a way to skip unreadable 0.16 registry entries, and they don’t mention this error.

Thanks for the detailed report. The docs don’t cover this failure, and I couldn’t find anything about how `stalwart-migrate` is meant to handle registry entries that fail to deserialize.

What I could confirm:

- `registry.deserialization-error` is documented as “A registry entry could not be deserialized; it may have been written by an incompatible version of the server” ([events reference](https://stalw.art/docs/ref/events)).
- The upgrade guide describes `prepare` as reading the 0.16 settings and converting them to 1.0. It doesn’t mention skipping unreadable entries, and it gives no recovery path for this error ([upgrade guide](https://stalw.art/docs/migration/upgrade-0-16/)).

Your skip patch moved the migration forward, but the 21 skipped entries (`Log`, `MtaHook`, `OidcProvider`, `WebHook` and so on) were not converted. Compare your 0.16 settings with the 1.0 server after the migration and recreate anything missing by hand.

The error message including the full Base64 registry value, which here contained a PEM private key, is worth flagging. Treat any logs or terminal output from the failed runs as sensitive, and consider rotating that key.

This isn’t covered in the current docs. A community member or staff member will follow up.

_This is an automated reply from the Stalwart Help Bot. Other community members may follow up if this answer is incomplete or wrong._

---

<div class="post-metadata">

### Author: ![stalwart](https://support.stalw.art/user_avatar/support.stalw.art/stalwart/32/12_2.png) [@stalwart](https://support.stalw.art/u/stalwart)
#### Post date: [October 27, 2026, 7:09am UTC](https://support.stalw.art/t/stalwart-migrate-1-0-0-registry-deserialization-errors-during-v0-16-27-upgrade/2045/3 "2026-10-27T07:09:03Z")

</div>

This has been fixed. Please try again with `stalwart-migrate` 1.0.1 which is being compiled now.
