What Emails Addresses Get Rejected by List Detective?​


While working on a project for a friend, we decided to introduce a proper email validation logic on the front-end and add some extra validation rules on top of the standard email address syntax check.

While the emails would go out from a different system, this naturally got me thinking about the List Detective feature of Salesforce Marketing Cloud. Its importance is crucial for email deliverability, but the rules seem to be opaque.

The official documentation describes List Detective as:

a proprietary Marketing Cloud database of bad email addresses that your Lists are “scrubbed” against whenever they’re imported.

The database includes known email spam traps, blocklist addresses, wireless domains, retired (no longer active) email companies or webmail providers, global unsubscribes, and mistypes.

source: List Detective Overview

That’s great, but what happens when List Detective encounters a new address in a domain it doesn’t know? The documentation claims it’s a database, but maybe it works more like an algorithm and has some rules that could be discovered.

Being curious, I decided to shed some light onto the topic.

The process involved throwing thousands of email addresses at this tool and seeing what could and couldn’t get through. You can read about this in this section.


The Structure of Email Addresses

Before we dive into the weeds of this topic, let’s just agree on the naming convention:

With that out of the way, we can just dive right into the findings.


The 4 rules of List Detective

Here’s what I was able to gather from my tests. The methodology of finding those rules or patterns is described later in the article.


1. Spam Traps

The words spamblacklistblocklist can’t appear anywhere in the email address:

  • ❌ Not in the local part
    • spam@sfmclistdetectiverocks.com
    • spam+tag@sfmclistdetectiverocks.com
    • notaspamtrap@sfmclistdetectiverocks.com
    • xxxblacklistxxx@sfmclistdetectiverocks.com
    • xxxblocklistxxx@sfmclistdetectiverocks.com
  • ❌ Not in the domain
    • hello@spam.com
    • hello@notaspamtrap.com
    • hello@thisisnotablacklistreally.xyz
    • hello@xxxblocklistxxx.xyz
  • ❌ Not even in the tag
    • example+spam@gmail.com

While it is a common practice to have multiple addresses and use a less personal one for registrations, sometimes the spam string could appear by accident.


2. Forbidden Local Parts

We’re all standing on should of giants and I can’t write this part without mentioning the excellent research done by Cameron Robert and Abikarsa Kristanto published in this article: “Email Usernames blocked by Salesforce Marketing Cloud” about “Role-Based” email addresses.

In short:
some email addresses do not represent individual people, but rather roles they play in organizations. A classic example of this would be this email address: “info@sfmc.quest” – multiple people could be responding to messages to this inbox.

This is not really something you would want to support as a B2C (business-to-consumer) platform.

The following words are only prohibited if they are the full local-part (exist before the “@” sign without any other characters):

  • abuse
  • email
  • feedback
  • hostmaster
  • info
  • invalid
  • junk
  • junkemail
  • junkmail
  • listserv
  • mail
  • mailerdaemon
  • marketing
  • news
  • newsletter
  • nobody
  • noc
  • noemail
  • none
  • noreply
  • null
  • ops
  • orders
  • postmaster
  • press
  • privacy
  • remove
  • root
  • security
  • subscribe
  • support
  • unsubscribe
  • usenet
  • uucp
  • webmaster
  • www

I’m not listing spam, blocklist and blacklist here as they are already included in the 1st Rule.

Why are some words red? Well, things got complicated when I was writing the first draft of this article…


Your Mileage May Vary Here

While discussing my findings with a friend, I noticed that a different SFMC account was not rejecting some of the words. The actual word list for this rule might be different for your stack or SFMC instance.

In my tests “admin” is a valid local part passing the validation on both accounts, but that might not be the case on your account.

The other account rejected those local parts:

  • abuse
  • info
  • invalid
  • junk
  • junkemail
  • junkmail
  • listserv
  • mailerdaemon
  • nobody
  • noc
  • noemail
  • none
  • noreply
  • nospam
  • null
  • postmaster
  • privacy
  • remove
  • root
  • spam
  • subscribe
  • support
  • unsubscribe
  • usenet
  • uucp
  • webmaster
  • www

But didn’t reject those:

  • email
  • feedback
  • hostmaster
  • mail
  • marketing
  • news
  • newsletter
  • ops
  • orders
  • press
  • security

Keep this in mind if you do your pre-production testing on a different account – you might have differences in import behavior which could impact your tests.


Examples that would be rejected:

  • ❌ stop@sfmclistdetectiverocks.com
  • ❌ remove@sfmclistdetectiverocks.com
  • ❌ support@sfmclistdetectiverocks.com
  • ❌✔️ press@sfmclistdetectiverocks.com can be rejected on one account, but accepted on a different one

Ask SF Support for help with specific role-based usernames

If you want to have a specific word enabled, support agents are able to ALLOW role-based usernames on your behalf.

Allowing usernames is not a Custom List Detective feature – it only serves as way of handing custom DENY entries.


Use +tags to bypass this rule

This rule can be easily bypassed for some inboxes that support sub-addressing: you can just add a +tag to cause List Detective to accept addresses from the list above.

  • ✔️ stop+tag@sfmc.quest
  • ✔️ none+shallpass@sfmc.quest
  • ✔️ mailerdaemon+banished@sfmc.quest

3. Prohibited .com domains

Email addresses in the following domains are blocked:

  • ad.com
  • address.com
  • box.com
  • client.com
  • domain.com
  • example.com
  • host.com
  • none.com
  • test.com
  • union.com

Only the .com versions of those domains seem to blocked by List Detective. Their .co.uk and .de versions pass validation without problems.

For example:

  • ❌ hello@domain.com will be blocked
  • ✔️ hello@domain.co.uk will be OK
  • ✔️ hallo@domain.de will be OK

Subdomains of the above domains are NOT rejected by List Detective:

  • ✔️ hello@mail.domain.com will be accepted

Use Custom List Detective to allow specific domains

Getting Custom List Detective enabled in your account will allow you to ask Salesforce Support agents to add specific domains to the “List Detective for Domains” custom allow list.

As with usernames / local parts, you only have the option to deny specific domains yourself.


4. Nobody’s Domains

For whatever reason the word nobody seems to be a special kind of an restricted word – if it will be anywhere in the domain part, the validation rejects the entire address.

Here’s a list of rejected email addresses with this word anywhere after the @ sign:

  • something@nobody.com
  • something@nobody.co.uk
  • something@nobody.de
  • something@nobody.gov
  • something@nobody.sfmc
  • something@nobodysuffix.com
  • something@prefixnobodysuffix.com
  • something@prefixnobody.com
  • something@something.nobody.com
  • something@something.nobody.de
  • something@nobody.sfmc.quest
  • something@nobody.sfmclistdetectiverocks.com

On top of being problematic in domains, this word also exists in the forbidden local parts (rule 2.), but is not as restrictive as spam / blocklist / blacklist, because it can be bypassed by using a tag in the local part.


🕵️ Could there be more?

Yes, of course there could be more. This is just something I was able to gather from my tests. I tried word sets in German and Spanish, but couldn’t find any more rejected words than those mentioned above.

If you find something that could expand this list, please let me know, I’ll try to recreate that and include here.


Live Test Tool

You can use the form below to check if an email would match any of the rules above as you type (there’s no need to push the button really).


❔ Email Validation

❔ Rule 1 Validation
❔ Rule 2 Validation
❔ Rule 3 Validation
❔ Rule 4 Validation

This tool uses currently the full list of prohibited local parts from the 2nd rule.


How Did I Learn This?

First I generated a basic list of words (some in many variations):

abuse, account, accounts, ad, address, admin, administrator, ads, advice, affiliate, affiliates, alert, analytics, announcement, announcements, application, apply, askus, assistance, billing, blacklist, blank, block, blocklist, blog, booking, box, business, cancel, career, careers, ceo, client, clients, collection, community, competition, competitor, compliance, conference, contact, contactus, coupon, coupons, customer, customerfeedback, customers, customerservice, customersupport, deal, deals, director, domain, donation, donations, donotreply, dontreply, download, downloads, dummy, dummyaccount, editor, education, email, employment, empty, end, enquiries, enquiry, event, events, exacttarget, example, fake, fakeaddress, fakeuser, faq, feedback, finance, form, forms, hello, help, helpdesk, helpline, honeypot, host, hostmaster, hr, ignore, inbox, info, infosec, inquiries, inquiry, invalid, invalidemail, invoice, invoices, issue, issues, job, jobs, joinus, junk, junkemail, junkmail, kickstarter, lead, leads, leave, legal, library, loremipsum, mail, mailerdaemon, manager, marketing, marketingcloud, marketresearch, media, mediacontact, mediacontacts, meetup, member, member-services, membership, memberships, minute, minutemail, news, newsletter, newsroom, no_reply, nobody, none, noreply, no-reply, notification, null, office, online, ops, optout, opt-out, order, orders, owner, partner, partnership, postmaster, pr, press, pressroom, privacy, problem, problems, procurement, product, promotion, promotions, prospect, prospects, public, publicrelations, quit, recruitment, release, reminder, reminders, remove, report, reports, research, reservation, reservations, resource, resources, return, returns, review, reviews, root, sales, salesforce, security, seminar, seminars, server, service, services, shipment, shipping, shop, spam, sponsorship, stop, subscribe, subscription, subscriptions, suggestion, suggestions, support, supportdesk, survey, surveys, team, technicalsupport, temp, temporary, test, testimonials, training, trap, trapemail, undeliverable, union, unsolicited, unsub, unsubscribe, update, updates, user, username, volunteer, voucher, warehouse, warranty, webinar, webinars, webinfo, webmaster, website, whitepaper, whitepapers, wholesale, wholesaler, workshop, workshops, www

Then I used a script to generate 24 different variations of email addresses including each word.

Here’s an example fragment of the set based on the word “invalid”:

Email Address VariantWhat’s being tested
invalid@sfmc.questPure local part in my domain
invalidsuffix@sfmc.questStart a local part in my domain
prefixinvalidsuffix@sfmc.questMiddle a local part in my domain
suffixinvalid@sfmc.questEnd a local part in my domain
something+invalid@sfmc.questThe word as an alias in my domain
invalid+alias@sfmc.questPure local part with an alias in my domain
invalid@sfmclistdetectiverocks.comPure local part in a .com domain
invalidsuffix@sfmclistdetectiverocks.comStart a local part in a .com domain
prefixinvalidsuffix@sfmclistdetectiverocks.comMiddle of a local part in a .com domain
suffixinvalid@sfmclistdetectiverocks.comEnd of a local part in a .com domain
something+invalid@sfmclistdetectiverocks.comThe word as an alias in a .com domain
invalid+alias@sfmclistdetectiverocks.comPure local part with an alias in a .com domain
something@invalid.comPure .com domain
something@invalid.co.ukPure .co.uk domain
something@invalid.dePure .de domain
something@invalid.govPure .gov domain
something@invalid.sfmcPure fake TLD domain
something@invalidsuffix.comStart of a .com domain
something@prefixinvalidsuffix.comMiddle of a .com domain
something@prefixinvalid.comEnd of a .com domain
something@something.invalid.com.com domain with a subdomain
something@something.invalid.de.de domain with a a subdomain
something@invalid.sfmc.questSubdomain of my domain
something@invalid.sfmclistdetectiverocks.comSubdomain of a .com domain

Next Step: API Validation

With the a set of of email addresses ready to go, it was time to validate them using the “validateEmail” REST API endpoint (POST /address/v1/validateEmail).

A single API call can only contain one email address, so I had to make the script iterate through an array and perform API calls with payloads like this:

{
    "email": "admin@sfmclistdetectiverocks.com",
    "validators": [
        "ListDetectiveValidator"
    ]
}

I’m only using the “ListDetectiveValidator” and decided to skip the two other validators:

  • SyntaxValidator” would not reject anything from my set as all of those addreses have a constructed correctly
  • MXValidator” would reject addresses in domains that don’t exist (like the “sfmclistdetectiverocks.com” that I’m using in my tests)

If the email address was correct, the response looks like this:

{
    "email": "admin@sfmclistdetectiverocks.com",
    "valid": true
}

This how a response looks if the email address was not accepted by List Detective:

{
    "email": "robertspamela@sfmc.quest",
    "valid": false,
    "failedValidation": "ListDetectiveValidator"
}

The email address above, contains the “spam” string by accident, poor Pamela Roberts.


Results

Out of initial 5784 email addresses only 156 were rejected by the validation API. I won’t list them all here, but will include this table that shows which test they failed:

With a view like this, it was easy to spot patterns and split them in a way to create as few validation patterns as possible.

  1. Spam Traps
    • Here all tests failed regardless of the place where those words appeared
  2. Forbidden Local Parts
    • Here only 2 tests failed for each word used, but they showed that if local parts consist only of the tested words they are rejected and it does not matter if it’s .com or any other top-level domain (TLD)
  3. Prohibited .com Domains
    • Some words were problematic only when used only as .com domains, so this had to become a new rule
  4. Nobody’s Domains
    • The word “nobody” got rejected in all domain tests and when uses as a pure local part – this last case was already covered by rule 2, so it made sense to separate the domain logic as distinct validation rule.

Additional local part test

After performing the first test, I did multiple other attempts to find new usernames that could cause issues.

This text file contains all of the words I tested:
list-detective-local-parts-test-words.txt


How to Use This Knowledge?

We now have a better understanding what addresses could cause issues with email deliverability, so let’s put this knowledge to use.


Find Problematic Email Addresses in Your CRM with SQL

First, let’s check how many customers could be affected by this already.

This query will identify addresses that would be problematic and see the exact reason why they would potentially be rejected by List Detective:

SELECT 
    Id,
	Email,
	EmailValidation
FROM (
	SELECT 
        Id,
		Email,
		CASE 
			WHEN Email LIKE '%spam%'
			OR Email LIKE '%blacklist%'
			OR Email LIKE '%blocklist%'
			   THEN 'Rejection: Spam / Blocklist / Blacklist'

			WHEN Email LIKE 'abuse@%'
        OR Email LIKE 'info%'
        OR Email LIKE 'invalid%'
        OR Email LIKE 'junk%'
        OR Email LIKE 'junkemail%'
        OR Email LIKE 'junkmail%'
        OR Email LIKE 'listserv%'
        OR Email LIKE 'mailerdaemon%'
        OR Email LIKE 'nobody%'
        OR Email LIKE 'noc%'
        OR Email LIKE 'noemail%'
        OR Email LIKE 'none%'
        OR Email LIKE 'noreply%'
        OR Email LIKE 'nospam%'
        OR Email LIKE 'null%'
        OR Email LIKE 'postmaster%'
        OR Email LIKE 'privacy%'
        OR Email LIKE 'remove%'
        OR Email LIKE 'root%'
        OR Email LIKE 'spam%'
        OR Email LIKE 'subscribe%'
        OR Email LIKE 'support%'
        OR Email LIKE 'unsubscribe%'
        OR Email LIKE 'usenet%'
        OR Email LIKE 'uucp%'
        OR Email LIKE 'webmaster%'
        OR Email LIKE 'www%'
        /* If you notice your account validates the smaller set 
           delete the one or all options below */
        OR Email LIKE 'email%'
        OR Email LIKE 'feedback%'
        OR Email LIKE 'hostmaster%'
        OR Email LIKE 'mail%'
        OR Email LIKE 'marketing%'
        OR Email LIKE 'news%'
        OR Email LIKE 'newsletter%'
        OR Email LIKE 'ops%'
        OR Email LIKE 'orders%'
        OR Email LIKE 'press%'
        OR Email LIKE 'security%'
		       THEN 'Rejection: Forbidden local part'

		WHEN Email LIKE '%@ad.com'
		  OR Email LIKE '%@address.com'
		  OR Email LIKE '%@box.com'
		  OR Email LIKE '%@client.com'
		  OR Email LIKE '%@domain.com'
		  OR Email LIKE '%@example.com'
		  OR Email LIKE '%@host.com'
		  OR Email LIKE '%@none.com'
		  OR Email LIKE '%@test.com'
		  OR Email LIKE '%@union.com'
		     THEN 'Rejection: Prohibited .com domain'

			WHEN Email LIKE '%@%nobody%'
			     THEN 'Rejection: Nobodys Domain'

            ELSE 'Valid' 
		END AS EmailValidation
	FROM Lead_Salesforce
	WHERE Email IS NOT NULL
	) S
WHERE EmailValidation IS NOT NUL

This is a simpler version that just returns email addresses that would be rejected:

SELECT 
    Id,
	Email
FROM Contact_Salesforce
WHERE 
    /* Rule 1: Spamtraps: */
       Email LIKE '%spam%'
    OR Email LIKE '%blacklist%'
    OR Email LIKE '%blocklist%'     

    /* Rule 2. Forbidden Local Parts */
    OR Email LIKE 'abuse@%'
    OR Email LIKE 'info%'
    OR Email LIKE 'invalid%'
    OR Email LIKE 'junk%'
    OR Email LIKE 'junkemail%'
    OR Email LIKE 'junkmail%'
    OR Email LIKE 'listserv%'
    OR Email LIKE 'mailerdaemon%'
    OR Email LIKE 'nobody%'
    OR Email LIKE 'noc%'
    OR Email LIKE 'noemail%'
    OR Email LIKE 'none%'
    OR Email LIKE 'noreply%'
    OR Email LIKE 'nospam%'
    OR Email LIKE 'null%'
    OR Email LIKE 'postmaster%'
    OR Email LIKE 'privacy%'
    OR Email LIKE 'remove%'
    OR Email LIKE 'root%'
    OR Email LIKE 'spam%'
    OR Email LIKE 'subscribe%'
    OR Email LIKE 'support%'
    OR Email LIKE 'unsubscribe%'
    OR Email LIKE 'usenet%'
    OR Email LIKE 'uucp%'
    OR Email LIKE 'webmaster%'
    OR Email LIKE 'www%'
    /* If you notice your account validates the smaller set 
       delete the options below */
    OR Email LIKE 'email%'
    OR Email LIKE 'feedback%'
    OR Email LIKE 'hostmaster%'
    OR Email LIKE 'mail%'
    OR Email LIKE 'marketing%'
    OR Email LIKE 'news%'
    OR Email LIKE 'newsletter%'
    OR Email LIKE 'ops%'
    OR Email LIKE 'orders%'
    OR Email LIKE 'press%'
    OR Email LIKE 'security%'

    /* Rule 3. Prohibited .com domains​ */
    OR Email LIKE '%@ad.com'
    OR Email LIKE '%@address.com'
    OR Email LIKE '%@box.com'
    OR Email LIKE '%@client.com'
    OR Email LIKE '%@domain.com'
    OR Email LIKE '%@example.com'
    OR Email LIKE '%@host.com'
    OR Email LIKE '%@none.com'
    OR Email LIKE '%@test.com'
    OR Email LIKE '%@union.com'

    /* Rule 4. Nobody's Domain​s: */
    OR Email LIKE '%@%nobody%' 

You might even find some customers with their addresses starting, for example, with mail@, but that just means this particular word was probably added to the validation after the address was added to List Detective.


Improve Your Registration Forms with JavaScript Validation

The best thing you could do to ensure no email addresses compatible with List Detective pass your forms is using the “validateEmail” REST API endpoint (POST /address/v1/validateEmail). I show some examples below as this is the method I used to find the rejection rules.

It can perform 3 validations for a single API call:

ValidationWhat does it do?
SyntaxValidator Checks if the email address construction is correct
ListDetectiveValidator Checks the address against the List Detective rules / database
MXValidator Checks if the domain has a mail exchange (MX) DNS entry. This means that an actual email account that’s being tested does not have to actually exist to be allowed by this type of validation.

Try to use it wherever you collect email addresses


Client-side JavaScript Fallback with REGEX

You could use the following regular expressions as a fallback to work client-side when the REST API is not available when maintenance or service disruptions occur.

General Email Validation Pattern

First we need to see if the provided email address has a proper syntax

const emailPattern = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
List Detective Rejection Patterns

Then we can validate the address against patterns representing the 4 rules:

const rule1Pattern = /(spam|blocklist|blacklist)/i;

// Select one of two prohibited local parts patterns depending on the implementation in your account
const rule2PatternA = /(abuse|email|feedback|hostmaster|info|invalid|junk|junkemail|junkmail|listserv|mail|mailerdaemon|marketing|news|newsletter|nobody|noc|noemail|none|noreply|nospam|null|ops|orders|postmaster|press|privacy|remove|root|security|subscribe|support|unsubscribe|usenet|uucp|webmaster|www)@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/i;
const rule2PatternB = /(abuse|info|invalid|junk|junkemail|junkmail|listserv|mailerdaemon|nobody|noc|noemail|none|noreply|nospam|null|postmaster|privacy|remove|root|spam|subscribe|support|unsubscribe|usenet|uucp|webmaster|www)@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/i;

const rule3Pattern = /^[a-zA-Z0-9._%+-]+@(ad\.com|address\.com|box\.com|client\.com|domain\.com|example\.com|host\.com|none\.com|test\.com|union\.com)$/i;

const rule4Pattern = /^[a-zA-Z0-9._%+-]+@.*nobody.*\.[a-zA-Z]{2,}$/i;

If the tested address would match any of the patterns, then the email would be rejected by List Detective. The very same regular expressions are being used in the Live Test Tool above.

💡 Bonus tip
Some customer might want to be smart and try to register with email addresses found on the website of your company, so you might want to disable the option to register with them as well.


That’s all, folks. Thank you for coming to my TED talk.

If you want to get updated when I publish something new like this, be sure
follow me on LinkedIn