- Fix Guides
- How to Fix Duplicate Contacts in Salesforce
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.
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
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.
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.
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.
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
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.
SELECT Email, FirstName, LastName, COUNT(Id) cnt FROM Contact GROUP BY Email, FirstName, LastName HAVING COUNT(Id) > 1 ORDER BY cnt DESC LIMIT 50Configure 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.
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.
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.
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.
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 DemoHow BuildForce prevents this in the first place
Duplicate records are a data-integrity risk; BuildForce flags them with conflict resolution paths.
Surface duplicate contacts across Salesforce + HubSpot before they corrupt your funnel.
Common Questions
More answers about this issue and how to resolve it.
Related fix guides
All fix guidesStop 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.