Issue Description
TL;DR: When trying to move between RocksDB and PostgreSQL the import fails on importing subspace_g as the table is not empty. Clearing the table does not work as the sole key in there is automatically re-created.
Please see a full reproduction, reason and description of the issue posted by another person (and then auto-closed by a bot) in this issue: --import aborts on its own store-identity marker, making backend migration impossible (0.16.15+) · Issue #3273 · stalwartlabs/stalwart · GitHub
Stalwart Version
v0.16.x
Installation Method
Docker
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
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
Confirming this bug — reproduced independently, v0.16.18
We hit this exact issue during a Postgres-backed migration (RocksDB source → PostgreSQL target, --export/–import). Full details:
- subspace_g (SUBSPACE_REGISTRY_PK) consistently exports truncated. We reproduced this 3 separate times from the same (stopped) source instance: a trial export, a full export, and a
fresh EXPORT_TYPES=registry-only export — all three produced a subspace_g file around ~74KB, ending mid-record.
- Cross-checked against a direct ldb --column_family=g --hex scan dump of the live RocksDB: the correct record count is 5193; the exported file only parses cleanly to ~4773 records
before hitting a truncated final entry (confirmed via LEB128-boundary parsing, not just file size).
- subspace_i, subspace_s, and other subspaces exported and imported correctly from the same source — this appears isolated to g specifically, likely size- or content-dependent (e.g.,
encoder buffer not fully flushed/closed for larger payloads).
- Consequence downstream: since g holds the RegistryClass::PrimaryKey/Reference entries, an import missing this data results in domain/account objects existing (import of s succeeds
fine) but all inbound SMTP RCPT TO resolution failing with 550 5.1.2 Relay not allowed for every domain — the domain(name) lookup misses entirely, even on a fresh cache. This is a
silent, hard-to-diagnose failure: the admin UI and CLI queries (which apparently read via a different path) show all data present and correct, while live mail delivery is completely
broken until g is manually rebuilt.
- Workaround: bypass --export/–import for g entirely — extract directly from the live RocksDB via ldb --column_family=g --hex scan, and load into the target via COPY … FORMAT csv (not
FORMAT text — Postgres’s text-format backslash-escaping conflicts with the \x-prefixed hex bytea representation and corrupts the data with embedded NUL bytes).
Happy to share more detail (schema version, exact repro steps) if useful for tracking this down.
Fixed in v0.16.19 (yet to be released).