Manual pages

shardpostctl-export(1)

Export an account to an archive, verify it and restore it.

SHARDPOSTCTL-EXPORT(1) ShardPost Manual SHARDPOSTCTL-EXPORT(1)

NAME

shardpostctl-export - export an account to an archive, verify it and restore it

SYNOPSIS

shardpostctl export -o file account
shardpostctl archive verify [--json] file
shardpostctl restore [-account target] [-acl] [-activate-sieve] [--json] file

DESCRIPTION

An account can be written to a single archive file and put back from it, with the IMAP identities intact: mail clients do not have to download everything again after a restore.

The archive

Format shardpost-account-export, version 1: a tar stream with a header, then per mailbox its description (id, name, UIDVALIDITY, UIDNEXT, HIGHESTMODSEQ, subscription, special-use, ACL, annotations), per message a description (UID, GUID, flags, MODSEQ, internal and save date, POP3 UIDL, size, SHA-256) immediately followed by the message as stored, then the Sieve scripts, and last a manifest with the checksum of every entry.

Not in the archive: subscriptions to mailboxes that do not exist, server annotations (among them the JMAP identities and the JMAP vacation response), the script jmap-vacation (a copy the server writes of that vacation response; a restore skips it in an older archive too), the trace switch, and the quota limit (it comes from the user database). The full-text index is not stored either; it is rebuilt from the messages.

export

Streams the account into file, which must not exist yet, and verifies it afterwards. Role: export.

The export does not lock the account. Each mailbox is read as it was when the export reached it; messages deleted in the meantime are listed in the manifest as skipped, deleted mailboxes as skipped_mailboxes. For an exact point in time, hold the account in the director first.

If the export fails midway, the archive ends with complete: false and is refused by both archive verify and restore. A download that breaks off leaves no file behind. There is no overall timeout on the download; -timeout only bounds the wait for the response and each pause without data.

archive verify

Reads the archive and checks every message against its description and every entry against the manifest. It needs no server, so a backup can be verified where it is kept. Prints what the archive holds.

restore

Verifies the archive completely, then imports it through the account import: mailboxes with their UIDVALIDITY and ids, messages with UIDs, flags, MODSEQ, dates and POP3 UIDLs, then UIDNEXT and HIGHESTMODSEQ per mailbox, the ACLs, the annotations and finally the Sieve scripts. Every mailbox is checked against the target's inventory and reported as verified. Role: import.

A restore is repeatable: messages that are already there are skipped, so a run that broke off can simply be repeated. The target must be empty or hold the same data; a mailbox with the same name but a different UIDVALIDITY and messages in it is a conflict.

While the restore runs, the account is locked like during an import. Afterwards the change log starts behind the restored state, so clients with a QRESYNC cache synchronize once in full.

Restoring into another account

With -account the archive goes into a different account, which is how you prove a backup without touching the original. Such a restore is deliberately isolated: ACLs are not restored (they would give real accounts rights on the copy) and no Sieve script is activated (the copy must not send vacation replies or forward mail). -acl and -activate-sieve switch that on if you really want it.

OPTIONS

-o file
Where to write the archive. The file must not exist.
-account target
Restore into this account instead of the exported one.
-acl
Restore ACLs even into another account.
-activate-sieve
Activate the exported Sieve script even in another account.
--json
Print the report as JSON.

EXAMPLES

Back up an account and check the result:

shardpostctl export -o user.tar user@example.org
shardpostctl archive verify user.tar

Prove the backup without touching the live account:

shardpostctl restore -account restore-test@example.org user.tar
shardpostctl mailbox list -all restore-test@example.org

Rebuild an account from its archive (this is also how a mailbox created with an old index shard size gets the current one). Hold the account first so nothing is delivered in between:

nauthilus-directorctl users hold set user@example.org --duration 15m \

--reason mailbox-rebuild nauthilus-directorctl users kick user@example.org --reason mailbox-rebuild shardpostctl export -o user.tar user@example.org shardpostctl plan purge user@example.org shardpostctl apply -wait <plan-id> shardpostctl restore user.tar nauthilus-directorctl users hold clear user@example.org \
--reason mailbox-rebuild-complete

Check an old backup on a workstation, without a server:

shardpostctl archive verify /backup/2026-09-20/user.tar

Inside the cluster the archive is written in the import sidecar, where a volume with room for it is mounted:

kubectl -n shardpost exec deploy/shardpost-server -c import -- \

shardpostctl -timeout 30m export -o /work/user.tar user@example.org

EXIT STATUS

0
Done; the archive is intact.
1
The restore partly failed. Run it again; what is already there is skipped.
65
The archive is damaged, incomplete or not a ShardPost archive. Nothing was restored.
67
No such account.
69
The export failed. No file was left behind.
73
The target file already exists or could not be created.
77
The caller lacks the role (export for the export, import for the restore).

SEE ALSO

shardpostctl(1), shardpostctl-job(1), shardpostctl-migrate(1)

The archive format and the restore are described in docs/admin-api.md.

2026-09-27 ShardPost 0.26.2

Rendered from docs/man/man1/shardpostctl-export.1 in the ShardPost repository.