How Message-ID Structure Affects Deliverability

  • August 2020
  • Engineering Memo · External Release

The Message-ID header is a required field in every email, serving as a globally unique identifier for the message. It enables threading in email clients, bounce tracking in delivery systems, and deduplication in ISP receiving infrastructure. What many operators do not realise is that the Message-ID is also evaluated by spam filters as a sender quality signal — its format, domain reference, and uniqueness characteristics all contribute to the overall message classification.

This note explains what a correctly structured Message-ID looks like, which patterns are associated with spam infrastructure and should be avoided, how PowerMTA generates Message-IDs by default, and why the domain in the Message-ID matters for filter trust.

The RFC 5322 Message-ID Format

RFC 5322 specifies the Message-ID format as: <local-part@domain>. Both the local part and the domain are required. The entire value is enclosed in angle brackets. The local part must be unique enough to ensure no two messages ever share the same Message-ID, even across different senders. The domain should be the sending domain or a subdomain of it — not an internal hostname, not "localhost", and not a domain unrelated to the sending programme.

A correctly structured Message-ID: <20200815.xk7m2p9.campaign42@mail.yourdomain.com>. This example includes a timestamp component (20200815 — the date), a random component (xk7m2p9 — ensures uniqueness even for messages sent at the same timestamp), a campaign identifier (campaign42 — enables attribution in bounce processing), and a recognisable domain (mail.yourdomain.com — matches the sending infrastructure's domain).

An incorrectly structured Message-ID: <12345@localhost>. The @localhost domain is a common default in poorly configured MTA software — it reveals that the MTA has not been configured to use the actual sending domain in Message-IDs. ISP filters recognise @localhost as a configuration indicator that the infrastructure is not professionally managed, and this signal contributes (modestly, but measurably) to spam classification.

Figure 1 — Message-ID Anatomy: Components of a Well-Structured Identifier

<20200815.xk7m2p9q3.cid-042@mail.yourdomain.com> Timestamp (YYYYMMDD) Random component (entropy) Campaign ID (optional) Sending domain (critical) Message-ID: Required header; uniqueness + domain reference = filter trust signal

Message-ID Patterns That Trigger Filter Signals

Spam filters have trained on millions of messages and have identified specific Message-ID patterns that correlate with spam-sending infrastructure. These patterns, when present in a message, contribute (typically modestly) to the overall spam score. The most significant patterns:

Sequential or predictable local parts. Message-IDs with sequential numeric local parts — <1@domain.com>, <2@domain.com>, <3@domain.com> — indicate a counter-based identifier that is trivially predictable. This pattern is associated with unsophisticated bulk sending software. Well-structured Message-IDs use sufficient randomness (at least 12 random characters from a large character set) that no two messages could plausibly share the same identifier even in a high-volume environment.

Extremely long or structured-looking local parts. Some spam systems generate Message-IDs with very long, structured local parts that appear to encode recipient or campaign data in a non-standard way — for example, <recipient_hash.list_id.campaign.timestamp.ip_address@domain.com>. The excessive length and structured appearance of these identifiers is associated with bulk system automation rather than individual message generation, and some filters treat this as a mild negative signal.

Domain references to unrelated or suspicious domains. A Message-ID that references a domain with no relationship to the sending domain — particularly a domain that is on a spam-related reputation list — generates a stronger negative signal than a misconfigured @localhost reference. For example, a message From: newsletter@legitimatedomain.com with Message-ID referencing a compromised or spam-associated domain is a flag that the message may have been injected through or relayed by problematic infrastructure.

Duplicated Message-IDs across multiple messages. Message-IDs must be globally unique. If the same Message-ID appears in multiple messages — which can happen when a sending system reuses identifiers due to a counter rollover or implementation bug — ISP deduplication logic may discard subsequent messages as duplicates, and the non-uniqueness of the identifier is itself a signal of poor implementation quality.

How PowerMTA Generates Message-IDs

PowerMTA generates Message-IDs automatically when messages do not include one from the sending application. The default generation uses the virtual MTA's configured EHLO hostname as the domain component, combined with a timestamp and a random component for the local part. The format is: <timestamp.random@ehlo-hostname>.

The critical configuration requirement: the EHLO hostname must be the production sending hostname, not an internal hostname or "localhost". If the smtp-source-host directive in the virtual MTA configuration specifies the correct sending IP and hostname, PowerMTA uses that hostname for Message-ID generation. If the EHLO hostname defaults to the server's internal hostname, Message-IDs will reference an unrecognisable domain that provides no trust signal — and may trigger the "domain unrelated to sender" filter signal if the internal hostname is clearly not related to the From: domain.

# Correct virtual MTA configuration for Message-ID generation
<virtual-mta vmta-promo>
  # The second argument becomes the EHLO hostname and Message-ID domain
  smtp-source-host   203.0.113.10 mail.yourdomain.com
  
  # This ensures Message-IDs take the form:
  # <timestamp.random@mail.yourdomain.com>
</virtual-mta>

# Incorrect — internal hostname will appear in Message-ID
<virtual-mta vmta-bad>
  smtp-source-host   203.0.113.10 internal-server-01.local
  # Message-IDs would be: <timestamp.random@internal-server-01.local>
  # This is a filter signal indicating misconfiguration
</virtual-mta>

For programmes where the sending application generates Message-IDs before injection (which is the preferred approach — the application knows the campaign context and can embed campaign identifiers), PowerMTA respects the Message-ID from the injected message and does not override it. The application-generated Message-ID should follow the format guidelines above: timestamp + random component + recognisable domain. The random component should be at least 12 characters from a case-insensitive alphanumeric set to ensure sufficient entropy at high sending volumes.

Message-ID and Bounce Attribution

Beyond its filter signal function, the Message-ID serves as the primary key for bounce attribution in DSN (Delivery Status Notification) messages. When a message bounces and the receiving server sends a DSN back to the sender, the DSN typically includes the original Message-ID of the failed message in the "Original-Message-ID" header. The bounce processing system uses this to look up which campaign, which recipient, and which list segment the bounced message belonged to.

Effective bounce attribution requires that the Message-ID contains enough information to perform the lookup. Two approaches: embed the necessary identifiers in the Message-ID local part (campaign ID, list ID, recipient hash), or use the Message-ID as a database key to look up attribution data. The embedding approach puts attribution data in the identifier directly, which works even if the DSN arrives after the campaign data has aged out of the primary database. The lookup approach keeps the Message-ID clean and short but requires that attribution data be retained for the full DSN arrival window (which can be days or weeks).

The embedding approach with campaign data in the Message-ID: <20200815.cmpid-042.listid-07.recipient-a1b2c3@mail.yourdomain.com>. The bounce processing system parses the local part to extract campaign ID (042), list ID (07), and recipient hash (a1b2c3), then looks up the full recipient record from the hash. This approach is more resilient to database changes over time but produces longer Message-IDs that should stay within reasonable length limits for client compatibility (under 200 characters total).

The Domain in Message-ID: FCrDNS Alignment

The domain in the Message-ID should ideally forward-resolve in DNS — it should have an A record or be a subdomain of a domain that has an A record. A Message-ID domain that cannot be resolved in DNS is a subtle signal that the infrastructure is not publicly registered and verified, which some filters treat as a minor negative indicator.

For typical production configurations where Message-IDs use the virtual MTA's EHLO hostname (mail.yourdomain.com), and the EHLO hostname has both an A record (resolving to the sending IP) and a PTR record (resolving from the IP to the hostname), the Message-ID domain automatically aligns with the FCrDNS configuration. This alignment — the same hostname that appears in the EHLO, the PTR record, and the Message-ID domain — is the consistency pattern that ISP filters expect from legitimately configured email infrastructure.

Any inconsistency in this alignment is worth investigating: a Message-ID that references a different domain than the EHLO hostname suggests that the message was injected through a relay that modified the SMTP session headers without updating the Message-ID, or that the application generates Message-IDs using a hardcoded domain that doesn't match the infrastructure being used for delivery. Both are configuration issues worth correcting to maintain the consistency that filter trust scoring rewards.

Verifying Message-ID Correctness in Production

Message-ID verification should be part of the pre-campaign template review process. The verification steps: send a test message through the production infrastructure to a test inbox at Gmail; retrieve the raw message source; find the Message-ID header; confirm the format matches <local-part@correct-domain> where correct-domain is the sending domain or a consistent subdomain; confirm the local part is sufficiently random and does not follow a predictable sequential pattern; confirm the domain resolves in DNS.

This verification takes 2 minutes and catches the most common Message-ID configuration errors: @localhost domain from unconfigured EHLO hostname, sequential local parts from a counter-based ID generator, or missing angle brackets from an application that generates non-RFC-compliant identifiers. Finding and fixing these issues during template review prevents them from appearing in production campaigns where they contribute to filter signals across potentially millions of messages.

The Message-ID is not the most impactful deliverability variable — reputation signals, authentication quality, and complaint rates all matter more. But it is one of the few deliverability factors that can be verified and corrected in 2 minutes during template review, and one that consistently incorrect configurations have been allowed to persist in production environments because it is never specifically checked. Including it in the template review checklist adds minimal overhead and eliminates a category of minor filter signals that, while small individually, accumulate across millions of messages into a measurable effect on spam classification probability at the margin.

Message-ID in DKIM Signing: The h= List Consideration

The Message-ID header is included in many DKIM signing configurations in the h= (signed header list). Including Message-ID in the signed headers provides an additional layer of message integrity — it ensures that the Message-ID cannot be changed after signing, which prevents a class of attacks where an intermediary replaces the Message-ID to disrupt bounce tracking or message threading.

The practical implication: if Message-ID is in the DKIM h= list and the message passes through a relay that modifies the Message-ID (which is uncommon but possible), DKIM verification will fail. For this reason, some operators exclude Message-ID from the h= list when messages transit through relays that may modify headers. The default PowerMTA DKIM header-list includes Message-ID, which is appropriate for direct-delivery environments where the message is not relayed through intermediate systems that might modify headers.

For environments that do relay through intermediate systems, reviewing which headers are in the DKIM h= list and excluding those that may be modified in transit prevents DKIM failures that would otherwise be attributed to encoding or configuration problems when the actual cause is relay-side header modification. The Message-ID is a lower-risk header than Content-Type or Content-Transfer-Encoding for relay modification, but it is worth confirming that no relay in the message path modifies Message-IDs before including it in the signed header list.

The In-Reply-To and References Headers: Message-ID Context

While not directly relevant to bulk email deliverability, the In-Reply-To and References headers that email clients generate for replied and forwarded messages reference Message-IDs of earlier messages in the conversation thread. For transactional email sequences — onboarding emails, support ticket updates, notification sequences — correct Message-ID generation ensures that follow-up messages thread correctly in email clients that support conversation threading.

For promotional bulk email, threading is less relevant — recipients do not reply to promotional campaigns in ways that generate In-Reply-To references. But for triggered email sequences where the programme sends multiple messages to a recipient as part of a journey (welcome email → onboarding day 2 → onboarding day 7), including the previous message's Message-ID in the References header of subsequent messages enables email clients to display the sequence as a conversation thread. This threading can improve the engagement experience for recipients who use threading-capable clients, as they can easily navigate the complete sequence.

Implementing References/In-Reply-To threading for triggered sequences requires that the sending application stores the Message-ID of each sent message and includes it in the subsequent message's headers. MailWizz does not implement this automatically for campaign-type sequences, but custom implementations using MailWizz's API can retrieve the previous message's Message-ID from the accounting log and include it in subsequent messages. The deliverability impact of threading is neutral — it is a user experience feature rather than a spam filter signal — but it is relevant context for understanding how Message-IDs are used across the full email conversation lifecycle, not just in the single-message deliverability context that bulk email operators most commonly consider.

Operational Standards for Message-ID Management

The operational standard for Message-ID management in a professionally run email infrastructure: all Message-IDs reference the production sending domain or a consistent subdomain of it; Message-ID local parts include sufficient randomness to guarantee uniqueness at the programme's maximum sending rate; the Message-ID domain forward-resolves in DNS; Message-ID format is verified during new template deployment and quarterly thereafter; and the PowerMTA EHLO hostname configuration is verified as part of each new virtual MTA setup.

These standards are simple to document and simple to verify. The verification process (sending a test message and checking the raw Message-ID header) takes 2 minutes. The configuration that produces correct Message-IDs (the smtp-source-host directive in PowerMTA with the correct hostname) is a one-time setup. The quarterly verification confirms that no configuration drift has introduced incorrect Message-ID generation.

Message-ID correctness is not the most impactful deliverability factor — optimising it alone will not rescue a programme with a 0.15% complaint rate or Low Gmail domain reputation. But it is one of the factors that complete, professional email infrastructure manages correctly as a matter of course. The programmes that consistently produce excellent deliverability outcomes are not those that address only the major factors — they are those that address the complete set of factors, including the minor ones that collectively add up to the consistent, high-quality signals that ISP reputation models interpret as professional-grade sending infrastructure. Message-ID correctness is one component of this complete quality standard, and one that is inexpensive to achieve and maintain.

Entropy Requirements at Scale: How Much Randomness Is Enough?

A programme sending 1 million messages per day must generate 1 million unique Message-IDs per day without any collisions. The entropy requirement is determined by the birthday problem: for a given local-part character space and length, what is the probability of a collision in 1 million identifiers?

For a local part using 36 characters (lowercase letters and digits), a 12-character random component has 36^12 = approximately 4.7 × 10^18 possible values. The birthday problem collision probability for 1 million random draws from this space is approximately 1 in 9 billion — effectively zero for practical purposes. Reducing to 8 characters provides 36^8 = approximately 2.8 × 10^12 possible values; collision probability for 1 million draws is approximately 1 in 5 million — still negligible but worth noting for very high-volume environments. At 10 million messages per day, 8-character random components produce a collision probability of approximately 1 in 50,000 — still very low but approaching the point where 12-character local parts are more appropriate.

The practical recommendation: use at minimum 12 random characters (lowercase alphanumeric) in the Message-ID local part, combined with a timestamp that ensures that even if two messages receive the same random component (a collision), they are differentiated by their timestamps. The combined uniqueness guarantee of timestamp + 12-char random is more than sufficient for any commercially realistic sending volume.

For programmes that include campaign or recipient identifiers in the Message-ID local part (for bounce attribution), these identifiers can serve double duty as uniqueness components. A structure like timestamp.campaignID.recipientHash12chars provides uniqueness through the recipient hash while also embedding attribution data, eliminating the need for a separate random component alongside the identifiers.

Handling Missing Message-IDs: What PowerMTA Does

Some sending applications inject messages without a Message-ID header — either because the application doesn't generate one, or because of a bug in the injection code. RFC 5322 requires that all messages include a Message-ID. When PowerMTA receives a message without a Message-ID header, it automatically adds one before delivering the message to the receiving ISP.

PowerMTA's auto-generated Message-IDs use the format described above — timestamp + random component + EHLO hostname domain. The auto-generation is correct and well-structured, but it means that the application has lost the opportunity to embed campaign attribution data in the identifier. If the sending application later receives a DSN with the Message-ID generated by PowerMTA, it may not recognise the identifier and cannot perform bounce attribution back to the specific campaign and recipient.

The solution: configure the sending application to always generate a Message-ID before injection, using a format that includes the attribution data the bounce processing system needs. This ensures that when DSN bounce messages arrive with the original Message-ID, the processing system can perform complete attribution without depending on PowerMTA's generic auto-generated format. Verifying that injected messages include a Message-ID header is a simple addition to the injection code's pre-send validation, and it catches the missing-header scenario before messages enter the delivery queue.

Message-ID is a small but complete story in email infrastructure correctness: its format carries trust signals for spam filters, its domain reference must align with the sending infrastructure, its uniqueness must be ensured through sufficient entropy, its local part can optionally carry attribution data for bounce processing, and its generation — whether by the application or PowerMTA — must produce RFC-compliant identifiers that reference the correct production domain. Each of these requirements is simple to meet and simple to verify. Together, they represent the standard of Message-ID management that professional email infrastructure maintains as a matter of operational discipline.

The Message-ID is one of those infrastructure details that sophisticated operators manage correctly without making a production of it — it is configured once, verified occasionally, and never becomes a problem. Programmes that have never considered it may be surprised by the @localhost references or sequential counters in their Message-IDs when they first inspect their raw message headers. The fix is a one-time configuration change and a 2-minute verification. The ongoing benefit is the elimination of a category of filter signals that, while minor individually, represent the type of unchecked technical debt that accumulates across many headers and configuration details into a meaningful cumulative effect on the infrastructure's professional quality signals.

Every detail of a well-managed email infrastructure contributes to the cumulative quality signal that ISP reputation systems observe across millions of messages. The Message-ID is one such detail — small in isolation, meaningful in aggregate, and straightforward to manage correctly with appropriate operational discipline.

Infrastructure Assessment

Our managed infrastructure configures PowerMTA virtual MTAs with correct EHLO hostnames that produce properly structured Message-IDs, verifies Message-ID format as part of new environment setup, and includes Message-ID verification in quarterly template review. Request assessment →