Not verified hands-on. This article was written from primary documentation rather than reproduced in an org, so it carries no tested-release badge. If you run it and something differs, say so in the comments and it gets tested and corrected.

Email-to-Case matches a reply to an existing case using a thread token, and when that token is missing or mangled the reply becomes a new case. Salesforce moved from a visible token in the subject line to a hidden header-based method, and most threading complaints come from an org still relying on the old behaviour or from a mail system that strips headers.

How a reply finds its case

The matching happens in order:

  1. Reference headers. The modern method. Salesforce writes References and In-Reply-To headers on outbound mail and reads them on the way back. Invisible to the customer, which is the point.
  2. The thread token in the subject or body, the [ ref:...:ref ] string. Still supported for compatibility, still ugly, and customers delete it.
  3. Nothing matches, so a new case is created.

When threading breaks, the first question is which method the org is configured for, in Setup under Email-to-Case. Orgs migrated from older configurations are often still on the token.

What breaks header threading

  • A mail gateway that rewrites headers. Some security appliances strip References. This is the most common cause in enterprises and it is not fixable in Salesforce.
  • The customer starting a fresh email rather than replying. No headers to carry, so a new case is correct behaviour even though it looks wrong.
  • A forward through a different system, which usually loses the chain.
  • A shared mailbox auto-responder replying to itself, which creates cases in a loop until somebody notices.

On-Demand versus the Email Agent

On-Demand Email-to-Case is the hosted version: you forward a mailbox to a Salesforce-generated address and nothing runs on your infrastructure. It is the right choice for almost everyone.

The downloadable Email-to-Case agent runs behind your firewall and exists for one reason: attachment size. On-Demand caps the total message size, and the agent handles larger attachments by storing them locally and linking. If that is not your constraint, do not run software you have to maintain.

Duplicate cases from one email

Two causes, and they look the same.

Multiple recipients. An email addressed to two routing addresses in the same org creates two cases. There is no de-duplication across routing addresses, so the fix is at the mailbox level.

A loop. Your auto-response replies to an address that replies back. Salesforce has loop protection that caps auto-responses to the same address in a time window, and it is a cap rather than a cure. Never send an auto-response to a no-reply or automated sender, and check the auto-response rule criteria exclude them.

The bits people forget to configure

  • The routing address must be verified. Until it is, mail silently goes nowhere.
  • The email service accepts attachments only up to a limit, and messages over it are rejected or truncated depending on settings.
  • Assignment rules do run for Email-to-Case, unlike a plain API insert. That is covered in case assignment rules.
  • The Contact is matched by email address. No match means a case with no contact, which breaks entitlement checks and community visibility.

Where the email actually lives

Inbound emails become EmailMessage records related to the case, not case comments and not tasks. That matters for reporting, for retention, and for storage: a busy support org accumulates a lot of EmailMessage data and the attachments sit in file storage separately.

It also matters for automation. A trigger on Case does not fire when a reply arrives, because the Case is not what changed. If you need to react to an inbound reply, the trigger goes on EmailMessage.

Frequently asked

Can I hide the thread token? Yes, by switching to header-based threading and removing the token from the templates. Test with your actual mail path before removing it.

Why is the case closed and still receiving replies? Threading does not care about status. A reply to a closed case reopens it or not depending on your automation, and if nothing handles it the reply is attached to a closed case nobody is watching.

How do I test this properly? From a real external mailbox, not from a Salesforce user. Internal mail can take a different path and thread when customer mail would not.