Mailgun发送邮件进入Outlook垃圾邮箱的排查与解决方案咨询
I’ve dealt with this exact frustration before—Outlook can be way pickier than Gmail even when you’ve nailed all the standard spam checks. Let’s break down how to diagnose and fix this, based on hands-on experience with Mailgun and Outlook’s spam filters:
1. Add Outlook-Specific Critical Headers
Outlook has its own set of header requirements that mail-tester doesn’t always account for. Here are the ones you should add immediately:
List-Unsubscribe: Even if you don’t have a public unsubscribe flow, including this header signals you’re following email best practices. Outlook prioritizes this heavily. Example:data['h:List-Unsubscribe'] = '<mailto:unsubscribe@mydomain.com?subject=Unsubscribe>, <https://mydomain.com/unsubscribe>';Message-ID: Mailcomposer might generate this automatically, but double-check it uses your verified domain (not a generic one). If it’s missing or misformatted, set it explicitly:data['h:Message-ID'] = `<${Date.now()}-${Math.random().toString(36).substr(2)}@mydomain.com>`;- Priority Headers: Avoid triggering "high priority" flags that Outlook associates with spam. Set these to normal:
data['h:X-Priority'] = '3'; data['h:X-MSMail-Priority'] = 'Normal';
2. Verify DKIM Alignment (Outlook’s #1 Authentication Check)
Outlook is hyper-strict about DKIM alignment. Even if your SPF and DKIM pass mail-tester, if your From domain doesn’t match the domain used in your DKIM signature, Outlook will flag the email as suspicious.
- Double-check your Mailgun domain settings: Ensure the
fromaddress in your code uses the exact domain you’ve configured DKIM for in Mailgun (e.g.,support@mydomain.com, not a third-party address). - Use Mailgun’s domain dashboard to confirm your DKIM record is properly aligned with your sending domain.
3. Audit Content for Outlook-Specific Triggers
Gmail is lenient with content that Outlook will flag as spam:
- Cut back on capital letters, exclamation points, and spam-adjacent keywords (e.g., "free", "guaranteed", "act now") in your subject line or HTML body.
- Ensure your HTML is well-formed: Outlook uses an old rendering engine, so unclosed tags or malformed tables can trigger spam filters. Run your HTML through a validator to catch issues.
- Add a physical mailing address to your email footer (required by CAN-SPAM laws, and Outlook explicitly looks for this to trust your emails).
4. Use Outlook’s Built-in Junk Analysis Tool
The fastest way to pinpoint the issue is to ask an Outlook recipient to check why the email landed in junk:
- Open the junk email in Outlook.
- Go to Home > Junk > Junk Email Options.
- Switch to the Selected Email tab and click Why is this in Junk?
This will give you a specific breakdown (e.g., "missing authentication", "content flagged") that you can address directly.
5. Warm Up Your Sending Domain/IP for Outlook
Even with perfect scores, new sending domains or IPs are treated as suspicious by Outlook. Build your reputation gradually:
- Start by sending small volumes of emails to trusted recipients who can mark your messages as Not Junk.
- Increase your sending volume slowly over 2-4 weeks—Outlook tracks sending patterns and will loosen restrictions as your reputation improves.
6. Check Your DMARC Policy
Outlook respects DMARC more strictly than many other providers. If your DMARC policy is set to p=reject while your reputation is still building, Outlook might junk or reject your emails. Stick with p=quarantine or p=none until you’ve established a consistent sending history.
Updated Code Implementation
Here’s how to adjust your sendHtmlEmail function to include all the recommended headers:
export const sendHtmlEmail = ({ from, to, replyTo, subject, html, inReplyTo }) => { return new Promise((resolve, reject) => { const mail = mailcomposer({ from, to, subject, html, text: htmlToText.fromString(html), messageId: `<${Date.now()}-${Math.random().toString(36).substr(2)}@mydomain.com>` // Explicit domain-aligned Message-ID }); mail.build((error, message) => { if (error) { reject(error); return; } let data = { to, message: message.toString("ascii"), 'h:X-Priority': '3', 'h:X-MSMail-Priority': 'Normal', 'h:List-Unsubscribe': '<mailto:unsubscribe@mydomain.com?subject=Unsubscribe>, <https://mydomain.com/unsubscribe>' }; if (replyTo) { data['h:Reply-To'] = replyTo; } if (inReplyTo) { data['h:In-Reply-To'] = inReplyTo; data['h:References'] = inReplyTo; } mailgun.messages().sendMime(data, (error, body) => { if (error) { reject(error); return; } resolve(body); }); }); }); };
内容的提问来源于stack exchange,提问作者Ben Flowers

