Manual pages

shardpostctl-deliver(1)

Deliver a message like a local delivery agent.

SHARDPOSTCTL-DELIVER(1) ShardPost Manual SHARDPOSTCTL-DELIVER(1)

NAME

shardpostctl-deliver - deliver a message like a local delivery agent

SYNOPSIS

shardpostctl deliver -d recipient [-f sender] [-m mailbox] [--no-sieve] [--no-enforce-quota] [--json] < message

DESCRIPTION

Reads one message (RFC 5322) from standard input and delivers it to one recipient, the way a local delivery agent does. This is the path an MTA uses when it hands mail over locally, and the same path LMTP takes: the recipient is resolved in the user database, the account's Sieve script runs, and the message is stored where the script decides.

The server puts Return-Path: <sender> (<> for the null sender), Delivered-To: recipient and its own Received field on top of the message, in that order, and removes a Return-Path the message brought along. The settings server.lmtp_return_path and server.lmtp_delivered_to switch the first two off.

The command prints where the message was stored, with mailbox and UID. If Sieve discarded the message, nothing is stored and the output says "discarded by sieve". When a Sieve reject sent a rejection message to the sender, nothing is stored either, the message counts as delivered, and the output says "rejected by sieve, rejection message sent to the sender". A reject of mail from the null sender sends no rejection message and counts as a discard. With --json the result carries disposition with the value stored, discarded or rejected.

Role: deliver and, for --no-enforce-quota, additionally deliver:noenforce.

OPTIONS

-d recipient
Envelope recipient, as an address or an account. Required. An alias is resolved to its canonical account.
-f sender
Envelope sender. Empty means the null sender, as for bounces.
-m mailbox
Store directly into this existing mailbox and do not run Sieve. Use it when a message must land in a specific mailbox, for example while re-injecting mail. A public folder is named the way a client sees it (Public/Support, see server.public_prefix) and needs the post right (p) for the recipient. There is no fallback: if the mailbox is missing the command fails with 67, if the right is missing with 77. A mailbox of another account is not a delivery target.
--no-sieve
Do not run the user's Sieve script; the message goes to INBOX.
--no-enforce-quota
Store even if the account is over its limit. The usage is still counted. This is what a local delivery must do when a bounce is not acceptable.
--json
Print the result as JSON: the account, the stored copies and the disposition.

EXAMPLES

Deliver a file as if it had arrived by mail:

shardpostctl deliver -d user@example.org -f sender@example.net < mail.eml

Put a message back into a specific mailbox, without letting Sieve move it again:

shardpostctl deliver -d user@example.org -m Archive < 933.eml

Re-inject a message that was exported earlier:

shardpostctl message export user@example.org INBOX 933 > 933.eml
shardpostctl deliver -d user@example.org --no-sieve < 933.eml

Deliver a system notice to an account that is over quota:

shardpostctl deliver -d user@example.org --no-enforce-quota < notice.eml

Check whether delivery works at all, end to end:

printf 'From: test@example.org\nSubject: probe\n\nbody\n' \

| shardpostctl deliver -d user@example.org --json

EXIT STATUS

The codes follow sysexits.h, so an MTA can act on them:

0
Delivered (or deliberately discarded by Sieve, or rejected by a Sieve reject that sent a rejection message to the sender).
64
Usage error, or the server refused the request as malformed.
67
No such recipient or mailbox.
69
The message was rejected by a Sieve ereject, by a reject that sends no rejection message (automatic or list mail, no relay, a relay that refused it, or sieve_reject_mode=protocol in sieve.settings), or it is too large.
70
The server sent an answer the client did not understand.
73
Over quota.
75
Temporary failure. The MTA should try again.
77
The caller lacks the role, or the recipient may not post into the mailbox named with -m.

SEE ALSO

shardpostctl(1), shardpostctl-acl(1), shardpostctl-message(1), shardpostctl-sieve(1)

2026-10-01 ShardPost 0.35.2

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