Knowledge base

Handing a message to a program on the same node

pipe delivery
A program instead of a receiver

A queue of the pipe type does not establish connections. For each new recipient it starts the program from the command line and writes the message to its standard input. What the program does with it is up to the program.

The usual use is parsing bounces and complaints: the return address domain is set up as a pipe queue, and everything that arrives there goes straight into the handler, bypassing a mailbox.

The special local domain. It collects mail to all recipients on the node’s local domains — the node determines them by the machine name and by its host-name lines. The manual’s caveat is important: PowerMTA does not read /etc/aliases and .forward, so the familiar unix mail forwarding does not work here.

The main trap is one process per recipient. The program is started for each new recipient, not per batch and not once. A handler that takes half a second to start will eat the whole node at a thousand bounces a minute. For a flow the http-delivery type fits better: there is one handler there, living its own life.
What the Hub does. It does not use it. Messages with bounces and complaints are parsed on the node itself by the engine’s built-in processors — <bounce-processor> and <feedback-loop-processor> — and what goes to the Hub are accounting records via the webhook. If a handler program on the node is needed after all, pipe fits a rare flow, and for a frequent one a webhook is better.
Example configuration
# parsing bounces with a program on the same node
<domain bounces.example.com>
    type pipe
    command "/opt/bounce/parse --envid \"$envid\" \"$user\""</domain>

# all mail to local recipients — into procmail
<domain local>
    type pipe
    command "/usr/bin/procmail -t -Y -d $user"</domain>
The quotes around substitutions are not for decoration: an address may contain spaces, and without them it will fall apart into several command-line arguments.
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▶

Using pipe on a flow

§ 11.21

What it costsThe program is started for each recipient. At a thousand messages a minute that is a thousand processes a minute — the node gets loaded by launches, not by mail.
How to spot itThe node’s load average grows together with the pipe queue, while sending has not increased.
How to do it rightFor a flow use the http-delivery type: there is one handler there, and it copes with the load itself.

Expecting /etc/aliases and .forward to work

§ 11.21.1

What it costsPowerMTA does not read them — the manual says so plainly. Forwarding set up in the familiar unix way silently does not trigger.
How to spot itMail to local addresses arrives in the handler instead of being forwarded by aliases.
How to do it rightSet up forwarding with the alias line in the PowerMTA configuration, not with system files.
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.
How to check on the node
Whether the handler works is visible from the queue itself: for the pipe type deliveries go without connections:
pmta show settings bounces.example.com/vmta1 | grep -E '^type|^command'
pmta show queues | grep -i bounces.example.com
A growing pipe queue with a program set usually means it does not start — check permissions and the path. The Hub does not create queues of this type.
In the Hub
Cost of a mistake
dangerous: effects outlast a rollback
Scenarios
Receiving inbound mail