Knowledge base

How the node responds to the receiving server's words

critical

<smtp-pattern-list>
The only thing that triggers backoff mode

The block matches the receiving server’s replies against regular expressions and performs an action on a match. Its entries are all of one kind — reply: an expression and an action side by side.

This is the trigger for all of backoff mode. Directives with the backoff- prefix describe what will happen, and a match here decides when. Without such a list all that machinery is dead (backoff-mode).

There are several actions. Switching the queue into backoff mode and back (mode=backoff, mode=normal), disabling the source address (disable-source-ip), sending the queue into retries immediately (defer-queue, optionally with its own interval), skipping an MX record and bouncing the message instantly.

A separate note on retries. The manual stipulates: a queue that has gone into backoff mode does not automatically go into retry mode. If you need both, the second action is written explicitly.

Behind a proxy, disabling an address is keyed by the proxy client address, not by the node’s address — a subtlety from the first part of the manual that is easy to forget.

The block has almost no directives — the rules are the block’s syntax, not named settings. The manual’s index gives it a single line, even though it is the most responsive mechanism in the configuration.

The main trap is confusing it with the sending address selection block. The configuration has a similar name, pattern-list, and it is about something entirely different: rules for selecting a sending address by the sender’s domain, living in the submission block. This block reacts to the receiving server’s replies during delivery; that one decides which address to send from. The names differ by one word, and the sides of the node are opposite.
What the Hub does. It does not write this block — our reaction to the receiving server’s replies lives outside, in the scheduler: it sees refusals through telemetry and decides on its own.

But the similarly named pattern-list the Hub does write — in the submission block, as the line that selects a sending address by the sender’s domain. Whoever looks for the reaction to refusals in our configuration and finds that name will be mistaken.

🔴 Hence the consequence: backoff mode is fully configured on our side (backoff-mode), but it cannot switch on by itself — there is no switch. A queue is put into the mode either by a command or by the Hub’s scheduler. The difference is speed: the engine would react right in the connection, while the scheduler learns from telemetry seconds and minutes later.

Recommended values

The block has no values of its own — there are actions written next to an expression:

Action What it does When appropriate
mode=backoff switches the queue into backoff mode a reputation refusal, “too many errors”
mode=normal returns it to normal a reply meaning the mail was held temporarily
disable-source-ip disables the source address a refusal naming a specific address
defer-queue immediately sends it into retries where waiting for the next attempt is pointless

Write expressions from the receiving server’s words, not from codes. Large receivers share codes, while the reason differs in the text: 421 too many errors and 421 try again later are different events under one code.

Start small. One or two expressions for the most frequent refusals are more useful than a long list: each rule is an automatic action, and an error in it is automatic too.

The action table with advice and the “by words, not codes” rule are ours. From the manual here are the block’s entry format, the set of actions, the caveat about retry mode and how address disabling behaves behind a proxy.
Example configuration
# a pattern list and a reference to it from the receiver block
<smtp-pattern-list block-errors>
    reply /^421 .* too many errors/ mode=backoff    reply /blocked.*spamhaus/ mode=backoff
</smtp-pattern-list>
<domain aol.com>
    smtp-pattern-list block-errors
    backoff-max-msg-rate 1/h
</domain>
The highlighted line is the manual’s example. Without the reference below, the list applies to no queue: the block by itself only describes rules.
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 ends3 mistakes▶

Confusing it with the sending address selection block

§ 3.3.7.32

What it costsThe similar name pattern-list in the submission block selects a sending address by the sender’s domain. Whoever looks for the reaction to refusals and finds that name decides it is configured — while it is not.
How to spot itThe configuration has a pattern list, but the queues never go into backoff mode.
How to do it rightLook at the full name and at which block holds the reference. The reaction to the receiving server lives only in the receiver block.

Writing a list and not referring to it

§ 3.3.15

What it costsThe block by itself only describes rules. Without a reference line in the receiver block, no queue applies it, and the whole backoff mode setup stays idle.
How to spot itThe list is in the configuration, but the queue modes never change.
How to do it rightAdd a reference line to the receiver block — at the right level: node, pool or sending address.

Expecting backoff mode to send the queue into retries by itself

§ 3.3.20

What it costsThe manual says the opposite: one does not entail the other. The queue slows down but keeps trying on the previous schedule unless the second action is written.
How to spot itThe queue is in backoff mode, yet attempts come at the same frequency as before.
How to do it rightAdd the retry action next to the switch into backoff mode — optionally with its own interval.
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 block itself lives at the root of the file and is not inherited. What is inherited is the reference to it — the smtp-pattern-list line in the receiver block, by the usual merge rule: from the general pattern to the exact one and across the levels node, pool, sending address. So different queues of one domain can have different lists in effect.
How to check on the node
Check both that the list exists and that something refers to it:
grep -n -A6 '^<smtp-pattern-list' /etc/pmta/config
pmta show queues
A list without a single reference applies to nothing. The second command shows the queue modes: if none has ever been in backoff mode while the list exists, either there is no reference or the expressions do not match what the receiving server actually replies.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Troubleshoot deliverability · Sending address rotation
Priority
critical