Knowledge base

remove-header

<source>set by the Hub

Which headers to cut from the message
in the configuration this is a lineremove-headerinside the block <source>
What must not reach the recipient

The value is a comma-separated list of names, not a single name: the line is not repeated, it is extended.

Headers are removed at delivery, not when the message is queued — the manual says so directly. That is, in the spool the message is stored intact, and the removed headers can be seen until it goes out.

An empty string (“”) erases the list inherited from a broader block. This is the only way to cancel inheritance: listing names does not cancel it, it only adds.

The directive also works on the recipient side. The manual says it can be written in <source> or in <domain>, and it does not have to be defined in both. The chapter 15 index knows only the source position — but the recipient settings output (§ 6.3.16) prints remove-header “” among the others, which confirms that the recipient form exists, it is just undocumented.

The main trap is the signature. DKIM signs the listed headers, and removing a signed one breaks verification at the recipient. The manual nowhere states the order of “sign first or remove first,” and the engine has its own list of signed headers — and some of them, per § 3.3.10.26, cannot be removed at all.

Check this with a message to your own mailbox, not by reasoning: a broken signature looks worse to the receiver than an extra service header.

What the Hub does. It writes it — the same list in every source it generates: X-PreviewEmail, X-Mailer, X-Mailer-RecptId, X-Mailer-Sent-By, X-Priority.

These are sending platform headers: from them the recipient (and the receiver) can tell exactly which product assembled the message, and X-Priority is also considered a sign of bulk mail.

The Hub removes the reception mark not with this line but with add-received-header false — it turns adding off entirely, so there is nothing to clean out through the list.

Recommended values

What to set. The list is assembled from whatever reveals your infrastructure:

Value When
do not write it the submitting platform sets no headers of its own
a comma-separated list of names the usual case: clean out the traces of the sending platform
“” cancel the list inherited from a broad block

It is not worth putting headers covered by the signature into the list — and especially not the ones the engine always signs.

The list syntax, removal at delivery, the caveat about two blocks and erasing with an empty string come from the manual, § 3.3.7.9. The recipient default is visible in § 6.3.16. The list of non-removable headers is from § 3.3.10.26.
Example configuration
# this is how the Hub writes the configuration — sending platform headers
<source 0/0>
    remove-header X-PreviewEmail,X-Mailer,X-Mailer-RecptId,X-Mailer-Sent-By,X-Priority</source>
One line, five names separated by commas. There is no need to repeat the directive — the list is extended within it.
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▶

Putting a signed header into the list

§ 3.3.10.26

What it costsRemoving a signed header breaks signature verification at the recipient, and the message looks forged. Some headers the engine always signs and does not allow removing at all.
How to spot itReceivers report an invalid signature after the list was edited.
How to do it rightCheck the list against the list of signed headers and test with a message to your own mailbox.

Repeating the directive instead of listing

§ 3.3.7.9

What it costsThe value is a list, not a single name. A second line in the same block does not extend the first but replaces it, and some of the headers stay in the message.
How to spot itNot all headers are cleaned out of the message, only the last ones listed.
How to do it rightKeep one comma-separated list in one line.

Trying to cancel the inherited list by listing names

§ 3.3.7.9

What it costsInheritance here is additive: the list from a broad block comes to the narrow one, and listing names in the narrow one does not cancel it. The header keeps being removed where it was needed.
How to spot itMore is removed in the narrow block than is written in it.
How to do it rightCancel with an empty string, and list what is needed again.
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.
Reference data
Syntax
remove-header <header-list>
Values
header names separated by commas; an empty string erases what is inherited
Applying
reload, no restart needed
Queue
will not touch what is already queued
Where to write it
<source>
How many times
once in the block
Everything here comes from the manual, with the section.
Inheritance
The directive lives in <source> and follows source merging: a connection falls under all address blocks that cover it, and a narrow one overrides a broad one. Inheritance here is additive: the list from a broad block goes to the narrow one, and it can be cancelled only with an empty string. There is also a separate recipient form — but it is not described in the index.
How to check on the node
The list is visible in the configuration, the result in the headers of a delivered message:
grep -n 'remove-header' /etc/pmta/config /etc/pmta/virtualhost.txt
Check it with a message in a seed mailbox: the listed headers must not be in it, and the DKIM signature must pass. The second matters more: a broken signature is worse than an extra header.
In the Hub
Managed at
Infrastructure → Node parameters
Value
The Hub picks it itself — pace, warm-up stage, metrics
Cost of a mistake
reversible: harms only while it is set
Scenarios
Sender isolation