Knowledge base

add-x-virtual-mta-header

<source>

Whether to add a header with the stream name to the message if there is none
in the configuration this is a lineadd-x-virtual-mta-header falseinside the block <source>
Let the message itself say which address it went out from

The default is false. With yes the node adds a header with the name of the stream the message is delivered through — if there is no such header yet.

The point is a copy of the message taken further down the path. A message that reaches you from a seed mailbox, from a complaint or from a recipient says by itself which address it went out from. There is no need to search accounting for that.

The flip side is exactly the same. The header reaches the recipient, and the recipient learns how the fleet is organized. This is a deliberate trade-off, not a setting that is “useful by default.”

The main trap is enabling this together with hiding the source. One line removes traces of the internal setup from the message, the other adds the stream name to it. Together they contradict each other, and the one that adds wins: the header stays.
What the Hub does. It does not write it. The stream name for every message comes in accounting and via webhook, so there is no reason to sign messages. If investigating by copies becomes necessary — for example, from seed mailboxes — it will have to be enabled deliberately, with the understanding that stream names will become visible to recipients.
Recommended values

What to set. The decision comes down to one question — whether investigating by a message copy matters more than keeping names private:

Value When
no (default) always, as long as the stream name is available from accounting
yes investigations go by message copies rather than node data

If you enable it, make the stream names neutral in advance: recipients will see them.

The false default and the “only if there is no header yet” rule come from the manual. The advice about neutral names is ours.
Example configuration
# the message is signed with the stream name — the recipient sees it too
<source 10.0.0.0/24>
    add-x-virtual-mta-header yes</source>
If the message already carries X-Virtual-MTA, the node adds nothing — the line works only “if there is no header.” Paired with an enabled retain-x-virtual-mta, the result is the same: the stream name in the delivered message.
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▶

Enabling it together with hiding the source

§ 3.3.7.36

What it costsThe settings contradict each other: one removes traces of the internal setup, the other adds the stream name. The expectation that “the message says nothing about us” is not met.
How to spot ithide-message-source is enabled, yet the delivered message has X-Virtual-MTA with an internal name.
How to do it rightPick one. For investigations take the stream name from accounting — it is always there and invisible to the recipient.

Enabling it on the whole node for the sake of one task

our experience

What it costsThe stream names of the entire fleet become visible to all recipients, although they were needed to investigate one mailing.
How to spot itThe header appears in messages that have nothing to do with the task under investigation.
How to do it rightPut the line into a narrow <source> block — for the submission under investigation — and remove it afterwards.
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
add-x-virtual-mta-header <boolean>
Values
yes | no | true | false
Default
false § 3.3.7.54
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 merges by the source rule: a narrower block overrides a broader one. It makes sense to enable it selectively — for the submission whose messages you plan to investigate by copies — rather than in <source> 0/0.
How to check on the node
The most reliable way is to send a message to yourself and look at the source. From the configuration:
grep -n -B5 add-x-virtual-mta-header /etc/pmta/config
The header may be missing from the delivered message even with the line enabled — if the message brought its own X-Virtual-MTA and retain-x-virtual-mta is left off: then the node strips the one it brought and will not add its own.
In the Hub
Cost of a mistake
reversible: harms only while it is set
Scenarios
Sending address rotation