Salesforce Dictionary - Free Salesforce GlossarySalesforce Dictionary
All errors
Integration

DUPLICATES_DETECTED: Use one of these records?

Salesforce's Duplicate Rules engine flagged your record as a fuzzy match for an existing one. Different from `DUPLICATE_VALUE`, which is a hard unique-field constraint. The fix is either to skip the duplicate, merge with the existing record, or pass `allowSave=true` if you legitimately want to keep both.

Also seen asDUPLICATES_DETECTED·Use one of these records·duplicates detected api·duplicate rule blocked save

Duplicate Rules are configured in Setup → Duplicate Rules. They run on save and use Matching Rules to identify near-duplicates by fuzzy-matching on selected fields (Name + Email + Phone, etc.). When a rule's action is "Block", your save is rejected with this error.

How to read the response

The API returns a structured response, not just an error string:

{
  "errors": [{
    "statusCode": "DUPLICATES_DETECTED",
    "message": "Use one of these records?",
    "fields": [],
    "duplicateResult": {
      "allowSave": true,
      "duplicateRule": "Standard_Account_Duplicate_Rule",
      "duplicateRuleEntityType": "Account",
      "errorMessage": "...",
      "matchResults": [{
        "entityType": "Account",
        "rule": "Standard_Account_Match_Rule_v1_0",
        "matchRecords": [{
          "record": { "Id": "0016xxx", "Name": "Acme Corp" },
          "matchConfidence": 0.95
        }]
      }]
    }
  }]
}

The duplicateResult.matchResults array tells you which records were flagged as duplicates and how confident the engine is.

Fix 1: skip and log

If your integration's job is "ingest new records, skip duplicates," catch the response and log:

Database.SaveResult[] results = Database.insert(records, false);
for (Database.SaveResult r : results) {
    if (!r.isSuccess()) {
        for (Database.Error e : r.getErrors()) {
            if (e.getStatusCode() == StatusCode.DUPLICATES_DETECTED) {
                // Log + skip
                System.debug('Duplicate detected: ' + e.getMessage());
            }
        }
    }
}

For REST: catch the 400 status with DUPLICATES_DETECTED and skip.

Fix 2: allowSave=true to override

If you're sure both records should exist (e.g., one is a customer, the other is a vendor that happens to share a name), pass DuplicateRuleHeader.allowSave=true:

Database.DMLOptions opts = new Database.DMLOptions();
opts.duplicateRuleHeader.allowSave = true;
opts.duplicateRuleHeader.runAsCurrentUser = true;
Database.SaveResult r = Database.insert(record, opts);

For REST, the equivalent is the Sforce-Duplicate-Rule-Header: allowSave=true HTTP header.

Fix 3: merge into the existing record

If the dupe is genuine and you'd rather merge:

// Find the matched record
List<Database.MatchRecord> matches = ...; // from the duplicateResult
Id existingId = matches[0].getRecord().Id;

// Update the existing record with new data instead of creating
Account existing = [SELECT Id FROM Account WHERE Id = :existingId];
existing.Description = newRecord.Description;   // merge in
update existing;

For Contacts and Leads, Salesforce has a built-in merge DML operation that consolidates two records and reparents children. Apex merge is the formal way:

Lead master = ...; Lead duplicate = ...;
merge master duplicate;   // duplicate gets soft-deleted, its children move to master

Tuning the rules

If your team is getting too many false positives, the Matching Rule is too lenient. Tune by changing matching algorithms:

  • Exact match on Email + Fuzzy on Name → more permissive, fewer false positives
  • Fuzzy on Email → more matches, more false positives

Setup → Matching Rules lets you adjust per-field. Test changes on a sample dataset before activating.

A common surprise: Matching Rules don't fire by default

A Duplicate Rule needs an active Matching Rule. Both must be active for the rule to fire. If you created both but only activated the Duplicate Rule, no errors fire — the engine has nothing to match against.

Related dictionary terms