Fix Guide

How to Fix Duplicate Contacts in Salesforce

Step-by-step fix guide with AI-powered diagnosis from BuildForce.

Duplicate Contacts in Salesforce come from three sources, in order of how much damage they do: integrations creating new records when they fail to match an existing one (HubSpot, Marketo, Pardot are usual suspects), manual imports via Data Loader that bypass the UI's dedup checks, and Lead-to-Contact conversions where the existing Contact isn't surfaced. The native fix is a two-step Salesforce configuration plus an integration-side change: in Setup → Duplicate Management, build a Matching Rule that defines what counts as a duplicate (email exact + optional fuzzy name fallback) and pair it with a Duplicate Rule set to 'Block' (not 'Alert') for the Create action. Then in each integration, set the upsert key to Email or a stable external ID so syncs update instead of insert. For records already in the database, the Duplicate Jobs feature (Enterprise/Unlimited only) generates merge candidates in bulk; for Professional Edition, Data Loader plus a SOQL group-by-email query is the manual fallback.

Matching RulesDuplicate RulesIntegration DedupBulk Merge

Duplicate Contacts is the rare problem where the volume tells you the root cause. If you have hundreds of duplicates with mostly-clean email addresses, it's an integration — something is upserting badly at scale. If you have dozens with weird email casing or whitespace differences, it's manual imports. If you have hundreds where one record is from 'Lead Conversion' and the other was a pre-existing Contact, your sales team is converting without searching first.

The damage is compounding. Every duplicate Contact attached to a Marketing Cloud journey sends two emails to the same person. Every duplicate attached to an active Opportunity creates split sales credit. Every duplicate counted in a board-level metric inflates the number. The cost of cleaning them up grows with the square of how long you've waited — merge a 50-record duplicate cluster today and it's a 30-minute job; merge the same cluster after another year of campaign activity and you're untangling 18 months of related activities, tasks, and opportunities.

The most important configuration step isn't the rule itself — it's setting the Duplicate Rule to 'Block' rather than 'Alert'. 'Alert' shows the user a warning and lets them proceed. Through the API (which is what integrations use), 'Alert' is silent and lets the record save anyway. 'Block' actually returns a DUPLICATE_DETECTED error that the integration must handle. Many teams have 'Alert' configured and believe they're protected; they're not.

Duplicate Jobs is available in Enterprise, Performance, Unlimited, and Developer editions; NOT in Professional or Essentials. Professional Edition orgs must rely on Data Loader + SOQL group-by queries for bulk dedup. The Standard Contact Duplicate Rule ships disabled — admin must explicitly enable and configure the Action setting.

Source: Salesforce Help — Duplicate Management Setup, Spring '26

Symptoms

Same customer appears multiple times with different contact records

Email notifications going to the same person twice after campaigns

Sales reps seeing multiple 'same company' accounts with split contact lists

Integration sync creating new records instead of updating existing ones

Reports showing inflated contact counts that don't match expected numbers

Root Causes

1

Duplicate Rules not configured or set to 'Allow' instead of 'Block'

Salesforce ships with Duplicate Rules in 'Alert' or disabled mode. Unless set to 'Block', users can create duplicates with just a warning. Integration APIs bypass UI warnings entirely.

2

Integration upsert keys not set

Integrations like HubSpot and Marketo create new records when they can't match an existing one. Without a configured external ID field or email-based match key, every sync creates new records.

3

Mismatched email formats

Matching on email fails when the same address appears as 'John@Company.com' and 'john@company.com', or when email aliases and forwarding addresses are used inconsistently.

4

Lead-to-contact conversion without deduplication

Converting Leads to Contacts without checking for existing Contact records creates duplicates. Salesforce doesn't automatically merge the Lead's activity with an existing Contact.

How to Fix It — Step by Step

1

Audit existing duplicates

Run Salesforce's built-in Duplicate Jobs (Setup → Duplicate Management → Duplicate Jobs) to get a count of matching records. This is available in Enterprise and Unlimited editions.

Example
SELECT Email, FirstName, LastName, COUNT(Id) cnt FROM Contact GROUP BY Email, FirstName, LastName HAVING COUNT(Id) > 1 ORDER BY cnt DESC LIMIT 50
2

Configure Matching Rules

In Setup → Duplicate Management → Matching Rules, create or enable rules for Contact matching. Use 'Email Exact' as the primary match criterion, with 'Name Fuzzy' as a secondary criterion for cases where email is blank.

3

Set Duplicate Rules to 'Block'

In Setup → Duplicate Management → Duplicate Rules, edit the Standard Contact Duplicate Rule. Change the Action from 'Allow' to 'Block' for the Create action. This prevents duplicates through the UI.

4

Configure integration upsert keys

In each integration platform (HubSpot, Marketo, etc.), set the upsert key to Email for Contact syncs. This tells the integration to update existing records instead of creating new ones.

5

Bulk merge existing duplicates

Use Salesforce's Duplicate Jobs to merge existing duplicates in bulk. Review the merge candidates, set the 'master' record policy (most recent activity, or most complete data), and run the merge job.

6

Monitor with BuildForce duplicate detection

Enable BuildForce's duplicate detection check to receive weekly reports on new duplicate records entering your org, with the source integration identified.

Real-world incidents we've seen

  • An e-commerce company whose Marketo→Salesforce sync had matched on Email but treated 'john@company.com' and 'John@Company.com' as different records. 14,000 duplicates accumulated over 8 months before someone noticed campaign sends were doubling. Fix: normalize emails to lowercase before the upsert, then merge the existing 14k duplicates with a master-record policy of 'most recent LastModifiedDate wins'.

  • A B2B sales org where Lead-to-Contact conversion was happening without the rep checking for existing Contacts first — Convert button was being clicked from list views without opening the record. ~600 duplicate Contacts created over 3 months. Fixed structurally by turning on 'Use Matching Rules' in the conversion flow and adding a required 'Check for Duplicates' step.

  • A nonprofit that ran a 60,000-record Data Loader import to backfill historical donors. The CSV had been deduped against the wrong export of the org. Result: 18,000 new duplicate Contacts on top of existing records. Recovery took three weeks because the merge process had to preserve the donor history attached to BOTH records — automated bulk merge couldn't handle the activity-attribution logic.

Let BuildForce diagnose and fix this automatically

Instead of following manual steps, connect your org and let our AI identify exactly what's broken and how to fix it — in minutes.

Book a Demo

How BuildForce prevents this in the first place

Data quality and security

Duplicate records are a data-integrity risk; BuildForce flags them with conflict resolution paths.

Cross-platform dedup monitoring

Surface duplicate contacts across Salesforce + HubSpot before they corrupt your funnel.

Common Questions

More answers about this issue and how to resolve it.

Stop debugging manually. Let AI do it.

BuildForce runs 200+ automated checks across your Salesforce org and tells you exactly what's broken and how to fix it.