Dependency Graph

Dependency Graph
related to related to child of child of duplicate of duplicate of

View Issue Details

IDProjectCategoryView StatusLast Update
0037355mantisbtemailpublic2026-08-25 06:38
Reportermichael_keiluweit Assigned Tocommunity  
PrioritynormalSeveritymajorReproducibilityalways
Status resolvedResolutionfixed 
Product Version2.28.0 
Target Version2.29.0Fixed in Version2.29.0 
Summary0037355: Message-ID of a submit notification is inherited by subsequent notifications for unrelated issues
Description

MantisBT reuses one global PHPMailer instance for all messages sent within a process. Only notifications for newly submitted issues set a Message-ID header (email_bug_info_to_one_user()); every other notification carries In-Reply-To instead. The cleanup between messages clears recipients, attachments, reply-to addresses and custom headers, but not PHPMailer::$MessageID.

The value therefore survives on the shared object, and every following message that does not set its own Message-ID is sent with it. As a result, notifications belonging to different issues go out under an identical Message-ID.

Consequences observed downstream:

  • Mail servers that deduplicate by Message-ID discard messages silently. This is the same failure mode already described in issue 0011123.
  • Ticket systems that resolve In-Reply-To against stored message IDs attach follow-ups to whichever issue happens to own the colliding ID, so notes for issue B end up filed under issue A.

The impact scales with $g_email_send_using_cronjob. With queued delivery the whole queue is flushed in a single process, so one submit notification can propagate its Message-ID to every later message in that run.

Steps To Reproduce
  1. Set $g_email_send_using_cronjob = ON
  2. Submit a new issue A. This queues a notification carrying Message-ID: md5(A.date_submitted)@host
  3. Add a bugnote to an existing, unrelated issue B
  4. Flush the queue so both messages are sent in the same process, A before B
  5. Inspect the raw headers of the message for B

Expected: a Message-ID unique to that message. Actual: the Message-ID of A's submit notification, while In-Reply-To correctly points at B's thread root.

The owning issue of any given Message-ID can be confirmed with email_generate_bug_md5(), i.e. md5( bug_id . date_submitted ), which is how the mismatch was identified.

Additional Information

Affected code:

  • 2.28.0 and later: core/classes/EmailSenderPhpMailer.class.php, EmailSenderPhpMailer::send() reuses $g_phpMailer, and reset() clears clearAllRecipients(), clearAttachments(), clearReplyTos() and clearCustomHeaders(), but not MessageID.
  • 2.25.7 up to 2.27.x: same defect in core/email_api.php, email_send(). The code moved into the new sender class in 2.28.0, the missing reset moved with it.

Not fixed in 2.28.4 (current release) nor in master.

Introduced by the fix for issue 0030127, which replaced the per-message PHPMailer object with a single reusable one in 2.25.7. Before that, a fresh object per send meant PHPMailer generated a unique Message-ID for each message.

Verified on a production instance running 2.28.0: in a sample of 64 notifications only 28 distinct Message-ID values occurred, and 9 of those were shared by more than one issue. Threading via In-Reply-To was correct in every case, the collisions came from the Message-ID side only.

Suggested fix: clear MessageID in the cleanup routine. An empty value is the PHPMailer default and makes createHeader() fall back to uniqueid@serverHostname(), with uniqueid regenerated per message in preSend(). Threading is unaffected, since In-Reply-To is added via addCustomHeader() and is already cleared. A pull request against master is ready to submit once this issue has a number.

TagsNo tags attached.

Relationships

related to 0030127 closeddregad new PHPMailer() is created for every outgoing email 
related to 0011123 closedvboctor Duplicate Message ID Header 

Activities

michael_keiluweit

michael_keiluweit

2026-08-25 04:17

reporter   ~0071373

PR: https://github.com/mantisbt/mantisbt/pull/2266

dregad

dregad

2026-08-25 05:40

developer   ~0071374

Thanks for the detailed analysis and pull request. I'll target this at 2.29.0 which I expect to release pretty soon.

Related Changesets

MantisBT: master 0647bf36

2026-08-25 04:08

michael_keiluweit


Details Diff
Clear PHPMailer Message-ID between messages

A single PHPMailer instance is reused for all messages sent within a
process, but reset() did not clear the MessageID property. Since only
notifications for newly submitted issues set a Message-ID, every
subsequent message inherited the value, so notifications for unrelated
issues were sent under an identical Message-ID.

An empty MessageID is the PHPMailer default and makes it generate a
unique one per message. Threading is unaffected, In-Reply-To is added as
a custom header and already cleared.

Fixes 0037355
Affected Issues
0037355
mod - core/classes/EmailSenderPhpMailer.class.php Diff File