Knowledge base

add-message-id-header

<source>set by the Hub

Whether to add a Message-Id header if there is none
in the configuration this is a lineadd-message-id-header falseinside the block <source>
Without this line Gmail cuts messages without an identifier

The default is false. With true the engine adds Message-Id to messages that do not have one; an existing one is not rewritten — there is a separate line for that, replace-message-id-header.

The identifier is mandatory under the message standard, and receivers — Gmail above all — treat its absence as a sign of a sloppy mailing.

Uniqueness is ensured not by this line but by host-id. The manual describes its purpose exactly so: a server identifier that keeps two engine installations from producing the same Message-Id. Its default is 0, which means on a fleet of nodes without an explicit number, identifiers can collide.

The main trap is forgetting the node number. The line adds an identifier, and on one server everything looks right. On a fleet of ten nodes with the default host-id 0, two messages can get the same Message-Id — and that is what complaints are investigated by and what the receiver’s logs are searched by.

The collision is not an engine error and does not show itself in any way until something is searched for by identifier.

What the Hub does. It writes true — in the source for submission from the machine itself, in a block for each address in “Who may submit mail”, and in every named login-based submission source. The reason is written right in the template: without an identifier, Gmail cuts messages.

The Hub sets the node number by the same construction: host-id gets the node’s number in the Hub, and it is unique. Two fleet servers will not produce the same identifier.

For warm-up itself the line does not fire: the sending library sets its own Message-Id, and the Hub stores it next to the send record. The line insures third-party submission platforms.

Recommended values

What to set. The answer is almost always the same:

Value When
true always, if submission does not come only from you — together with an explicit host-id
false (default) the submitting platform is known to set the identifier itself

Even in the second case the line does no harm: it does not touch an existing header. It is cheaper to set it than to figure out what each platform does.

The false default and the “an existing one is not rewritten” caveat come from the manual, § 3.3.7.4. The purpose and default of the node number — § 3.3.1.33. The Gmail part is our experience, recorded in the configuration template.
Example configuration
# the node number is the other half of the solution; without it identifiers can collide
host-id 7

<source 0/0>
    add-message-id-header true</source>
The first line lives at the root of the file, the second in a source. Separately, the first does nothing, and the second on a fleet of nodes produces colliding identifiers.
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▶

Adding identifiers without setting the node number

§ 3.3.1.33

What it costsThe number’s default is zero, the same on all fleet nodes. Two messages from different servers can get the same identifier, and searching for a message by it stops being a search for one message.
How to spot ithost-id is missing from the configuration or equals zero on several nodes at once.
How to do it rightGive each node its own number — any number unique within the fleet will do.

Expecting the line to rework someone else's identifier

§ 3.3.7.4

What it costsIt does not touch an existing header. If the submitting platform sets the identifier in an inconvenient form, this line will change nothing.
How to spot itMessages keep the platform’s identifiers even though the line is enabled.
How to do it rightThere is a separate directive for rewriting — but first it is worth deciding why that is needed.
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-message-id-header <boolean>
Values
yes | no | true | false
Default
false § 3.3.7.4
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. The node number, meanwhile, is set at the root of the file and is not split across sources — there is one for the whole installation.
How to check on the node
Both halves are checked together, the result — in the delivered message:
grep -n 'add-message-id-header\|^host-id' /etc/pmta/config /etc/pmta/virtualhost.txt
A host-id 0 line or its absence means identifier uniqueness across nodes is not ensured. Whether the adding worked is visible from a message without its own identifier in the seed mailbox.
In the Hub
Value
The Hub picks it itself — pace, warm-up stage, metrics
Cost of a mistake
reversible: harms only while it is set
Scenarios
Connect a sending platform