Email headers series. This is the tactical guide to the Message-ID header. For the full RFC catalog and other header deep-dives, see the headers and MIME hub →
Quick Message-ID reference
The Message-ID header is a globally unique identifier for every email message. RFC 5322 defines it, every threading system depends on it, and getting it wrong breaks conversation grouping, bounce correlation, DMARC forensic reports, and duplicate-detection at the receiver.
| Spec | RFC 5322 §3.6.4 (updates RFC 2822) |
| Syntax | <id-left@id-right> |
| Uniqueness | MUST be globally unique across all mail, past and future |
| Generation | The MUA (client) or the first MTA that processes the message |
| Character set | dot-atom-text on both sides of the @ |
| Not to be confused with | The id= field inside Received headers |
Message-ID is one of the oldest headers in email, and one of the most consistently mishandled. Every mail server writes it, most application code generates it wrong, and a broken Message-ID quietly breaks threading, bounce processing, and log correlation without any error visible to the sender. This guide covers the exact syntax, how ESPs generate it, what it is actually used for downstream, and the 10 mistakes that ship to production most often.
What the Message-ID header actually is
Message-ID is a mandatory header (per RFC 5322 §3.6.4, technically SHOULD, universally treated as MUST by receivers) that carries a globally unique identifier for the message. It looks like an email address wrapped in angle brackets:
Message-ID: <CADjJk5o8-P2HdVQ3=YkR4WvY9Nx4vP+H3Zw@mail.gmail.com>The identifier has two halves separated by @. The left side is the message-unique portion (random, timestamp-based, or a combination). The right side is a domain-like identifier that the generating system controls, typically the hostname of the composing MTA or ESP.
The Message-ID is written once, at the moment the message is created or first submitted, and never rewritten afterward. Every server that handles the message thereafter reads it, logs it, correlates on it, but does not modify it. This immutability is what makes it useful as a stable identifier across the delivery chain.
The exact syntax (RFC 5322 §3.6.4)
RFC 5322 defines the format precisely:
msg-id = [CFWS] "<" id-left "@" id-right ">" [CFWS]
id-left = dot-atom-text / obs-id-left
id-right = dot-atom-text / no-fold-literal / obs-id-rightIn practice, this means:
- Angle brackets are mandatory. A Message-ID without
<and>is malformed. Some receivers repair it silently, others reject the whole message. - The
@separator is required. A single-string identifier without@is not a valid Message-ID. - Character constraints. Both halves are
dot-atom-text: letters, digits, and a limited set of special characters (!#$%&'*+-/=?^_`{|}~) plus dots between atoms. No spaces. No angle brackets inside the value. - Case sensitive. RFC 5322 treats the Message-ID as opaque; case matters when comparing.
- Length. No hard limit, but keeping it under 100 characters is standard practice. Some legacy systems truncate above 255.
Valid examples
<20260702143512.abc123@smtp.example.com>
<CAF-mail1234567890@mx.gmail.com>
<5e3d2f4a-1b2c-4d5e-9f8a-1234abcd@postmark.local>Invalid examples
Message-ID: CAF-mail1234@example.com (missing angle brackets)
Message-ID: <abc.def.example.com> (missing @)
Message-ID: <abc def@example.com> (space in id-left)
Message-ID: <abc@def@example.com> (two @ signs)Where the Message-ID is generated
Client-side (MUA)
Modern desktop and mobile mail clients generate the Message-ID at send time, before the message hits the outbound SMTP server. Thunderbird, Apple Mail, Outlook (desktop), and most mobile mail apps write their own. The domain part usually reflects the client identity (Thunderbird, iPhone-Mail) or the outbound account’s domain.
Server-side (MTA and ESP)
The more common case for application-generated mail (transactional, marketing, cold outreach): the sending application does not set a Message-ID, and the outbound MTA or ESP generates one. Postfix’s cleanup daemon does this for locally submitted mail. Every major ESP does it for API and SMTP submissions.
Where both the client and the ESP would generate one, the ESP typically overrides the client-supplied Message-ID. This is deliberate: the ESP needs the domain part of the Message-ID to reflect its own infrastructure so that reputation and bounce tracking work correctly.
ESP Message-ID formats in the wild
| Provider | Format example |
|---|---|
| Gmail | <CADgY-Pjnkq3W...@mail.gmail.com> |
| Amazon SES | <0100017c3d...@us-west-2.amazonses.com> |
| SendGrid | <M4nSlwoGRWWlY9C...@geopod-ismtpd-3-1.example.com> |
| Postmark | <b8XXX-b8-b1e...@pm-bounces.example.com> |
| Mailgun | <202601011234.abc@mg.example.com> |
| Postfix (self-hosted) | <20260702143512.A1B2C3@mail.example.com> |
| Microsoft 365 | <PA5PR07MB89...@PA5PR07MB8935.eurprd07.prod.outlook.com> |
Each ESP encodes routing information in its Message-ID format. SES includes the region. SendGrid includes the sending pod. Microsoft 365 includes the tenant datacenter. This is not required by RFC 5322, it is operational instrumentation that the ESP reads back later when correlating bounces, opens, and complaints to the original send event.
The uniqueness requirement
RFC 5322 is emphatic: the Message-ID MUST be globally unique. Not unique per sender, not unique per day, not unique per receiver. Globally unique across all mail ever sent, and all mail ever to be sent, on the internet.
Nobody enforces this at the wire level. There is no central registry. The requirement is a load-bearing convention: the entire mail ecosystem depends on it holding in practice, even though no protocol makes it mandatory.
How generators actually achieve uniqueness
Every serious generator combines three elements:
- A time component. Nanosecond timestamp, or unix time plus a counter.
- A random component. Cryptographic random bytes, base64 or hex encoded, at least 64 bits of entropy.
- A domain identifier. The hostname or ESP domain, which makes collisions across systems impossible.
Combining these three gives a Message-ID that is unique with overwhelming probability. Timestamps alone are not enough (a busy MTA can send hundreds of messages in the same millisecond). Random bytes alone are not enough (birthday-paradox collisions become real at high volume). The domain suffix acts as a namespace, guaranteeing that two independent systems cannot produce the same ID.
What happens when uniqueness breaks
- Gmail thread collision. Two independent messages with the same Message-ID may get grouped into the same conversation view, or one may be treated as an update to the other.
- Duplicate delivery detection. Some receivers deduplicate on Message-ID; a repeated ID triggers a silent drop of the second message.
- Bounce correlation failure. ESPs and MTAs use the Message-ID (in the bounce report) to link back to the original send event. Non-unique IDs corrupt bounce statistics.
- Loop detection failures. Mail loop detection uses Message-ID history; a repeated ID can trigger false-positive loop rejections at forwarding gateways.
The role of Message-ID in email systems
Threading (In-Reply-To and References)
When you reply to a message, your MUA writes two related headers:
In-Reply-To:the Message-ID of the parent message.References:the chain of Message-IDs going back to the thread root.
Gmail, Outlook, Apple Mail, and most modern MUAs use this chain to build the conversation view. A missing or malformed Message-ID at any point in the chain breaks threading downstream.
Bounce correlation
When a message bounces, the receiving server generates a Delivery Status Notification (DSN) that includes the original Message-ID in the Original-Message-ID field of the DSN, or in the returned headers. ESPs read this field to link the bounce back to the original send. If your Message-IDs are not unique, you cannot correlate bounces to specific messages. See our hard bounce vs soft bounce guide for the DSN mechanics.
DMARC forensic reports
DMARC failure reports (RUF, when the receiver is configured to send them) include the original Message-ID of the failing message. Domain owners rely on this to identify which specific send triggered a DMARC failure. See our DMARC guide for context.
ESP suppression and reputation systems
ESPs use the Message-ID as the primary key for tracking a specific message through their infrastructure. Opens, clicks, bounces, unsubscribes, and complaints all get correlated to the Message-ID. Without a unique ID, per-message statistics collapse.
Log correlation across servers
Every mail server logs the Message-ID at accept, at queue, at delivery, at bounce. When debugging a delivery issue that spans multiple hops (submission MTA, relay, receiving MTA, filtering), the Message-ID is the join key that lets you follow the message end-to-end.
Reading a Message-ID in raw headers
Here is a real header block from a Gmail-received message, edited for brevity:
Delivered-To: user@example.com
Received: by 2002:a05:6402:1234 with SMTP id abc123.gmail.com;
Wed, 02 Jul 2026 07:14:32 -0700 (PDT)
Return-Path: <bounce+abc123@sender.example.com>
Authentication-Results: mx.google.com;
dkim=pass header.i=@sender.example.com;
spf=pass smtp.mailfrom=bounce+abc123@sender.example.com;
dmarc=pass header.from=sender.example.com
From: Marketing <news@sender.example.com>
To: user@example.com
Subject: Your July update
Message-ID: <20260702141234.7fa3b2c1@mta-05.sender.example.com>
Date: Wed, 02 Jul 2026 14:12:34 +0000
Content-Type: multipart/alternative; boundary="--boundary1234"The Message-ID appears in the block of headers written by the sender’s system. Its domain (mta-05.sender.example.com) tells you which specific MTA generated the message. The left side is a timestamp plus a random 8-character hex string, a straightforward and safe generation pattern.
How to inspect a Message-ID
Gmail: Show original
Open the message, click the three-dot menu, select “Show original”. The raw source appears with all headers, including Message-ID. Gmail also shows a summary card with the extracted Message-ID at the top of that page.
Outlook desktop
Open the message, File → Properties. The “Internet headers” box at the bottom contains the raw headers including Message-ID.
Command line via IMAP
openssl s_client -connect imap.gmail.com:993
a1 LOGIN user@gmail.com <app-password>
a2 SELECT INBOX
a3 FETCH 1 (BODY[HEADER])Postfix logs
grep "queue_id" /var/log/mail.log | grep "message-id="ESP dashboards
Every major ESP surfaces the Message-ID in its activity or event log. In SendGrid, it appears in the “Message ID” column of the Activity Feed. In SES, it is the return value of the SendEmail API call. In Postmark, it is the top-level identifier in the Messages tab.
10 common Message-ID mistakes
- No Message-ID at all. Custom SMTP clients that forget to write the header. Most MTAs auto-generate one on submission if missing, but if your code goes direct to a foreign relay without a rewrite, the message ships without a Message-ID and gets flagged by spam filters.
- Missing angle brackets.
Message-ID: abc123@example.cominstead ofMessage-ID: <abc123@example.com>. Some receivers repair, others reject. - Duplicate Message-IDs across sends. Using a static template value for testing, then shipping without regenerating for each message. Every recipient after the first sees a duplicate.
- Domain part that does not match From or authentication domain. Not required by RFC 5322, but suspicious to reputation systems. A message with
From: news@example.comandMessage-ID: <abc@spammer.example.net>reads as spoofed. - Timestamp-only IDs on a high-volume sender.
<20260702141234@example.com>at 1,000 messages per second causes collisions. Add a random component. - UUID without domain suffix.
<550e8400-e29b-41d4-a716-446655440000>is malformed. UUIDs are fine as the id-left, but the@domainis required. - Regenerating the Message-ID on forwarding. Forwarders that overwrite the Message-ID break the threading chain and DMARC forensic correlation. Preserve the original.
- Special characters unescaped in id-left. Spaces, parentheses, angle brackets, or non-ASCII characters in the local-part fail the RFC 5322 syntax and cause parsing errors at receivers.
- Message-ID longer than 255 characters. Some legacy MTAs (mostly ancient Sendmail installations) truncate at 255. Modern receivers do not, but you can safely stay under 100 characters.
- Random values without cryptographic entropy. Using
rand()ortime()-based IDs in high-volume production code. The collision math catches up fast. Use/dev/urandom,crypto.randomBytes(), or your language’s cryptographic random.
Message-ID FAQ
Is Message-ID mandatory in an email?
Technically it is a SHOULD per RFC 5322 §3.6.4, not a MUST. In practice, receivers treat its absence as suspicious. Spam filters penalize messages without Message-ID. Threading systems break. ESPs auto-generate one if the submitting application does not. For any production use, treat Message-ID as required.
Can I set my own Message-ID when sending through an ESP?
Sometimes. SendGrid, Postmark, and Mailgun accept a custom Message-ID via a specific header or API field, but they may append their own tracking suffix. Amazon SES and most transactional providers override any client-supplied Message-ID with their own. If you need a specific Message-ID for correlation with your app, check the ESP’s API documentation; if it is not explicitly supported, do not rely on it.
What is the difference between Message-ID and the id= field in Received headers?
They are unrelated. Message-ID is written once at message creation and identifies the message globally. The id= field inside a Received header is written by each MTA that handles the message; it identifies the message locally to that MTA’s queue and changes at every hop. Do not use the Received id= for cross-server correlation.
Should the Message-ID domain match the From domain?
Not required by RFC 5322. In practice, receivers and reputation systems prefer alignment: a message from news@brand.com with a Message-ID at @brand.com or @sendgrid.net (a known ESP) reads as legitimate. A message from news@brand.com with a Message-ID at @random.tk reads as spoofed. Alignment is not enforcement, but misalignment is a spam signal.
How does Gmail use Message-ID for threading?
Gmail’s threading uses a combination of Message-ID, In-Reply-To, References, and Subject. When you reply, your client writes In-Reply-To with the parent’s Message-ID and References with the full ancestor chain. Gmail follows this chain to group the conversation. If the chain is broken by a missing or reused Message-ID, Gmail falls back to subject-line clustering, which is less reliable and often groups unrelated messages.
What happens if I regenerate the Message-ID on every retry?
Anti-loop and anti-duplicate systems get confused. Retries with the same Message-ID are recognized as retries; retries with new Message-IDs look like independent messages, which can trigger duplicate delivery to the same recipient. Keep the Message-ID stable across retries of the same logical send. Only generate a new Message-ID for a genuinely new message.
Final words
The Message-ID header does more work than any other single line in email. Threading, bounce processing, log correlation, DMARC forensics, reputation tracking, and ESP analytics all pivot on it. When it is malformed, missing, or non-unique, none of them fail loudly. They just quietly produce worse results, and the sender rarely notices.
The safest posture: let your ESP or MTA generate it. Every major provider gets this right. When you do generate it yourself (custom app code, self-hosted MTA, or SMTP relay setup), follow the pattern: high-entropy random component + timestamp + domain suffix that matches your infrastructure. Never reuse. Never omit the angle brackets. Never omit the @.
For broader context, see our guides on the RFC 5322 message format, the DMARC authentication mechanism, and the bounce handling reference.
A clean list makes every Message-ID actually reach a mailbox.
SMTPing catches disposables, role-based, catch-all, syntax errors, dead mailboxes and traps before they turn your careful Message-ID into a bounce. 13 validation types, 25 free daily.
About the Author

Alaa · LinkedIn
Email infrastructure specialist with 8+ years of hands-on experience in SMTP, deliverability, and email verification. I’ve configured and troubleshot mail systems across Postfix, Exchange, and cloud relays, managed IP reputation and warmup campaigns, and built verification pipelines processing millions of addresses. My work spans DNS authentication (SPF, DKIM, DMARC, BIMI), bounce handling, blocklist monitoring, and compliance frameworks including CAN-SPAM and GDPR. I write every article on SMTPedia to give email professionals, developers, and marketers the accurate, RFC-grounded reference they need.
About SMTPedia
SMTPedia is an independent email industry reference covering SMTP, IMAP, POP3, email deliverability, marketing platforms, DNS authentication, and email verification. Every article is researched from official provider documentation, IETF RFCs, and industry best practices. Settings and configurations are verified quarterly.
We are cited as a source by ChatGPT, Microsoft Copilot, and thousands of email professionals worldwide. Learn more about our editorial process.

