Knowledge base

Two inbound report processors and what to do with them

bounce and feedback-loop processors
Half of the delivery picture arrives as messages

A node learns the fate of a message in two ways. In the conversation — and that gets into accounting by itself. By a message later — and this is what the processors are needed for.

There are two of them, and they are structured the same way. <bounce-processor> parses asynchronous bounces, <feedback-loop-processor> parses complaints. Each has its own address list, its own pair of decisions about the message’s fate and its own option to nest patterns.

Four lines decide everything:

Line Decides
deliver-matched-email what to do with what was recognized (default — discard)
deliver-unmatched-email what to do with the rest (default — deliver)
forward-unmatched-to where to forward what was not understood
forward-errors-to where to forward what parsing broke on

🔴 Two lines are connected in a non-obvious way: forwarding what was not understood works only with deliver-unmatched-email true. Otherwise the message is discarded earlier, and the forwarding address is useless.

Receiving is a separate question. A processor decides the fate of an accepted message. For the message to be accepted, relay-address and an MX record are needed; without them the report is rejected by anti-relay and never reaches parsing.

The main trap is thinking the processor allows receiving. It does not: the address list inside it filters what has already been accepted. The most common picture is a correctly configured processor with no messages, because anti-relay rejects them with a hard bounce.
What the Hub does. It writes both processors and both permitting lines: bounces are caught at bounce@bounce.<domain>, complaints at fbl@fbl.<domain>, and the result goes to telemetry as rb and f records. We also accept the role addresses dmarc@, postmaster@ and abuse@ — we have to, otherwise anti-relay rejects them.

🔴 And we have deliver-unmatched-email no in both. This means everything the processor did not recognize is discarded silently: aggregate DMARC reports that we ourselves requested with the rua record, service messages to abuse@ and everything written to postmaster@. The fix is a pair of lines: true plus forward-unmatched-to to a live mailbox.

Recommended values

The mechanism has no values of its own — they are set by four lines in each of the two blocks:

What is needed How
accept the message relay-address plus an MX record
catch it with a processor an address list inside the block
record the data happens by itself, as rb and f records
not lose everything else deliver-unmatched-email true plus forwarding
The structure of both blocks, the defaults of the four lines and the link between forwarding and allowed delivery come from the manual (§ 3.3.3, § 3.3.4). The analysis of what gets lost in our configuration is based on the Hub template.
Example configuration
# receiving, parsing and keeping everything else are three different things
relay-address /^bounce@bounce\./
<bounce-processor>    deliver-matched-email no
    deliver-unmatched-email true
    forward-unmatched-to postmaster@example.com
    <address-list>
        address /^bounce@bounce\./
    </address-list>
</bounce-processor>
Recognized bounces are discarded — their data is already in accounting. Everything else goes to a person rather than into the void.
yellow — — directive names, blue — blocks. They are highlighted the same way in the text of the card.
▲

Common mistakes and problems

what people get wrong and how it ends2 mistakes▶

Configuring a processor without allowing receiving

our experience

What it costsThe address list inside the block filters what has already been accepted. Receiving is allowed by relay-address; without it reports are rejected by anti-relay and never reach parsing.
How to spot itThe processor is configured, and there is not a single rb or f record in accounting.
How to do it rightAdd relay-address for the same addresses and check the MX record.

Discarding unrecognized mail at addresses people write to

§ 3.3.3.1

What it costsThe processor does not recognize aggregate reports, service messages and ordinary mail. With the no value all of this disappears without a trace.
How to spot itDMARC reports are requested with the rua record, but nobody has ever seen them.
How to do it rightdeliver-unmatched-email true plus forward-unmatched-to to a live mailbox.
Compatibility
PowerMTA 6.0
described in the manual of this version · platform: any
The vendor does not state the first version for every directive — there is no note here. The name also appears in the 5.0 edition of the manual.
Inheritance
The mechanism has no inheritance — the directives that enable it are inherited, and they live inside their block. There are exactly two processors, and their settings are independent.
⇄

Related entries

5 relations

How to check on the node
Check in accounting: records of both types should appear:
cut -d, -f1 /var/log/pmta/acct-*.csv | sort | uniq -c
rb and f records mean the processors work. Their absence while sending is going on is a signal: either the messages are not accepted (relay-address, MX record), or they are not recognized (patterns are needed in <email-patterns>).
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Bounce classification · Receiving inbound mail · Collect telemetry