70.1.9. pepsi-stage-bounce¶
rewrite a message into a delivery-status bounce
- Manual section:
1
70.1.9.1.1. Name¶
pepsi-stage-bounce - the bounce-generation stage of the Pepsi pipeline.
70.1.9.1.2. Synopsis¶
pepsi-stage-bounce [GLOBAL-OPTIONS] worker
70.1.9.1.3. Description¶
pepsi-stage-bounce is a stage program: it is run by pepsi-dispatch(1)
as a persistent worker, reading message ids on standard input, each identifying a
row of the pepsi.ingress table. It loads that row, refusing to act unless its
status is running,
and reads its own configuration from the message’s [stage-<stage>] section
(see pepsi.conf(5)).
It rewrites the message in place into an RFC 3464 delivery-status notification
(DSN): the envelope sender becomes the null sender (<>), the envelope
recipient becomes the original message’s sender, and the body becomes a
multipart/report quoting the original headers.
“The original message’s sender” is state.srs.original when
pepsi-stage-srs(1) recorded one, and the mail_from column otherwise.
The distinction matters on any relaying path, because SRS necessarily runs
before the delivery stage: by the time a DSN is composed here the envelope
sender is one of our own SRS aliases, and addressing the report to it would send
it out to the next hop and back in through our own MX to be decoded — surviving
the whole inbound pipeline as a null-sender message — only to reach an address
that was on the row all along. SRS is a return path for a bounce the next hop
generates; a report we write ourselves needs no such detour. See
pepsi.state(7). By default this is a failure
bounce (Action: failed); when the routing stage tags state.bounce with
kind = success it is instead a positive (Action: delivered) report.
The diagnostic and recipient are taken from the state the routing stage left
on the row. The DSN’s From: is the POSTMASTER address. The rewritten DSN is
left unsigned; the row is advanced to the stage’s NEXT_STAGE, normally
pepsi-stage-dkim-sign(1), which DKIM-signs it (as the postmaster’s domain)
before a delivery stage such as pepsi-stage-relay-to-internet(1) relays it.
A message that is already a bounce (it has the null envelope sender) is not rewritten: it is deleted and the deletion is logged. A bounce is never itself bounced (RFC 5321 §6.1).
DSN (RFC 3461): a failure bounce is generated only when the failed recipient’s
NOTIFY requested FAILURE. The NOTIFY/ORCPT/ENVID the stage
acts on are the ones the routing delivery stage copied onto the state.bounce
object (from the recipient’s state.dsn entry). The default — no NOTIFY
carried — is FAILURE, so ordinary mail still bounces; but NOTIFY=NEVER
(or a NOTIFY list without FAILURE) means the sender does not want a
failure report, and the message is then dropped without a bounce. When the
original ENVID and ORCPT were supplied they are echoed into the DSN as
Original-Envelope-Id and Original-Recipient.
A success report (kind = success) is generated only when the recipient
explicitly requested NOTIFY=SUCCESS (success, unlike failure, has no implicit
default); the routing stage emits one solely when the global [pepsi]
ORIGINATE_SUCCESS_DSN is enabled. A delay report (kind = delay,
Action: delayed) is generated only when the recipient requested
NOTIFY=DELAY; a delivery stage enqueues a copy of a still-undelivered message
here (see DELAY_DSN_AFTER in pepsi-stage-relay-to-internet(1)) while the
original keeps being retried. Both success and delay have no implicit
default.
The human-readable (text/plain) part of the bounce is, by default, a built-in
English notice. When the stage’s BOUNCE_MESSAGE option names a template, that
part is instead rendered from bounce-<NAME>.<lang>.body under the [pepsi]
TEMPLATE_DIR (a Mustache template; see pepsi.conf(5)). The
whole message state is the rendering context, so a delivery stage’s captured
next-hop detail (state.bounce.remote_mta / smtp_code / enhanced_status
/ phase / reply_text) lets the bounce state precisely why the next MTA
refused the message. Rendering is best-effort: any failure falls back to the
built-in text, so a bounce is always produced.
pepsi-stage-bounce performs no network delivery and issues no notification; the rewritten message is delivered by whichever stage NEXT_STAGE names.
70.1.9.1.4. Configuration¶
The bounce stage’s options (SERVER_NAME, POSTMASTER, the required
NEXT_STAGE and the optional BOUNCE_MESSAGE template) are documented in
pepsi.conf(5).
70.1.9.1.5. State¶
Inputs: state.bounce — the report context the routing stage left on the
row. Its kind (permanent ⇒ a failure Action: failed report,
success ⇒ Action: delivered, delay ⇒ Action: delayed) selects the
report type; diagnostic and failed_recipient are quoted in it; the
optional notify/orcpt/envid decide whether the report is emitted at
all and what is echoed; and the optional structured next-hop fields
remote_mta/smtp_code/enhanced_status/phase/reply_text (written
by the relay stages) are surfaced to the BOUNCE_MESSAGE template and, for
enhanced_status, into the DSN Status: field. A hand-staged message with no
state.bounce yields a generic failure notice.
Outputs: the stage rewrites the message in place and clears ``state`` to
null — the bounce is a new null-sender message that inherits none of the
original’s provenance (this is the one stage that does not preserve state).
The state layout is described in pepsi.state(7).
Transitions:
an incoming message that is itself a bounce (null sender) → finish (dropped, never re-bounced);
the recipient’s
NOTIFYdoes not request the report thiskindwould emit (failure has an implicit default;success/delaydo not) → finish (dropped without a DSN);otherwise the message is rewritten in place into a DSN and advanced to NEXT_STAGE (the signing/delivery tail).
The stage never pauses, fails or reroutes.
70.1.9.1.6. Commands¶
- worker
Run as a persistent pepsi-dispatch(1) worker, reading message ids on standard input.
70.1.9.1.7. Global Options¶
These global options precede the subcommand.
- -c FILE, –config FILE
Read the configuration from FILE instead of searching the default locations.
- -L LOGLEVEL, –log LOGLEVEL
Set the logging verbosity (
error,warn,info,debugortrace; defaultinfo).- -v, –verbose
Show log messages from all sources, including third-party libraries.
- -h, –help
Print a usage summary and exit.
- -V, –version
Print the version and exit.
70.1.9.1.8. Exit Status¶
- 0
The message was processed (rewritten and advanced, or dropped).
- 1
An error occurred: the message was not found or not
running, the stage was misconfigured, or a database error occurred. The reason is written to the log; pepsi-dispatch(1) marks a row stillrunningafter a non-zero exit asfailed.
70.1.9.1.9. Examples¶
Run the bounce stage on message 42 by hand (it must be running):
pepsi-stage-bounce -c /etc/pepsi/pepsi.conf 42
70.1.9.1.10. See Also¶
pepsi-config(1), pepsi.conf(5), pepsi.state(7), pepsi-stage-dkim-sign(1), pepsi-dispatch(1), pepsi-stage-relay-to-internet(1), pepsi-stage-relay-to-smarthost(1), pepsi-setup(1)
70.1.9.1.11. Bugs¶
Report bugs to the Pepsi issue tracker.