--- title: "Python smtplib: Missing Date/Message-ID Headers Break Mail Clients" domain: troubleshooting category: general tags: [email, python, smtplib, spam, rfc, spark] status: published created: 2026-04-29 updated: 2026-04-29 --- # Python smtplib: Missing Date/Message-ID Headers Break Mail Clients ## Problem Emails sent via Python's `smtplib` and `EmailMessage` appear on some mail clients but not others. The emails are delivered to the server and visible in Maildir, but specific clients silently suppress them. ## Root Cause Python's `EmailMessage` does **not** automatically add `Date:` or `Message-ID:` headers. These are required by RFC 5322. Without them: - **SpamAssassin** flags `MISSING_DATE` and `MISSING_MID`, and may set `X-Spam-Flag: YES` even if the overall score is below the spam threshold - **Mail clients** (e.g., Spark) may filter on the spam flag header and silently hide the message — no Junk folder, just invisible - **Other clients** (e.g., iPhone Mail, some Spark builds) may be more lenient and display the message anyway This creates a confusing situation where the same email appears on one device but not another, despite both using the same IMAP account. ## Fix Always include `Date` and `Message-ID` headers when constructing emails with `EmailMessage`: ```python import smtplib from email.message import EmailMessage from email.utils import formatdate, make_msgid msg = EmailMessage() msg['Subject'] = 'Your subject here' msg['From'] = 'sender@example.com' msg['To'] = 'recipient@example.com' msg['Date'] = formatdate(localtime=True) msg['Message-ID'] = make_msgid(domain='example.com') msg.set_content('Email body here') with smtplib.SMTP('mail.example.com', 25) as s: s.send_message(msg) ``` ## Verification After applying the fix, check that SpamAssassin no longer flags the headers: ```bash # Check email headers on the mail server grep -E 'MISSING_DATE|MISSING_MID|X-Spam' /var/vmail/domain/user/cur/ ``` A clean message should show `X-Spam-Status: No` with no `MISSING_DATE` or `MISSING_MID` in the test list. ## Key Takeaway Python's `EmailMessage` is a low-level builder — it trusts you to set all required headers. Unlike higher-level mail libraries or webmail interfaces, it will happily send a message with no date or message ID. Always add both explicitly in any script that sends email via `smtplib`.