HR API update employee endpoint fails with duplicate SSN error when merging legacy records during migration

We’re encountering duplicate SSN errors when updating employee records via the HR Core API during our legacy HRIS data migration to wd-r1-2024. The error occurs even though we’ve run deduplication scripts on our source data and confirmed each SSN is unique in the migration dataset.

The API response states ‘SSN already exists in system’ but doesn’t indicate which employee record contains the duplicate. We’ve migrated about 3,000 employees successfully, but the remaining 500 records fail with this error. When we manually check these SSNs in the Workday UI, we can’t find existing records with those numbers.

Our deduplication scripts validated SSN uniqueness across the source system, and we’ve formatted all SSNs consistently (XXX-XX-XXXX format). Could there be terminated employee records or historical data causing conflicts? Is there a way to query all SSN values including inactive employees through the API?

Your duplicate SSN errors during migration stem from three overlapping data quality issues that require systematic resolution:

1. Legacy Data Migration Complexity (addressing your historical data challenges): The core issue is that Workday maintains SSN uniqueness across ALL worker types and statuses - active employees, terminated employees, contingent workers, and even applicant records in the recruiting module. Your deduplication scripts only validated the migration dataset, not the existing Workday tenant data. During migration, you must deduplicate against the target system’s complete SSN inventory.

To build a comprehensive SSN inventory from Workday:

  • Get_Workers (Include_Terminated=true, Include_Inactive=true)
  • Get_Contingent_Workers (all statuses)
  • Get_Job_Applications (to catch applicant SSNs)
  • Get_Terminated_Workers (specifically for long-term terminated)

The 200 terminated worker matches you found explain part of your 500 failures. The remaining 300 are likely split between contingent workers (~100-150), applicants with SSNs on file (~50-75), and data quality issues in your source data (~75-100).

2. Deduplication Script Limitations (addressing your validation gaps): Your scripts validated SSN uniqueness within the migration dataset but missed several critical scenarios:

Formatting Normalization: Workday stores SSNs as 9-digit strings internally (no dashes), but accepts XXX-XX-XXXX format via API. Your deduplication must normalize both formats:


# Normalize SSN for comparison
ssn_normalized = ssn.replace('-', '').replace(' ', '')
if len(ssn_normalized) == 9 and ssn_normalized.isdigit():
    # Valid SSN format

Placeholder Detection: Legacy systems often use fake SSNs for employees without valid numbers. Flag and exclude these patterns:

  • 000-00-0000, 111-11-1111, 123-45-6789 (sequential test values)
  • 999-99-9999 (common placeholder)
  • SSNs where all digits are identical: 111111111, 222222222

Leading Zero Preservation: Excel and CSV exports strip leading zeros, converting 001-23-4567 to 1-23-4567. Your deduplication script must pad SSNs to 9 digits:


ssn_padded = ssn_normalized.zfill(9)

3. SSN Field Formatting Standards (addressing your API payload structure): The API accepts SSNs in XXX-XX-XXXX format, but inconsistent formatting in your payloads can cause validation failures that appear as duplicate errors. Ensure your update requests format SSNs consistently:

{
  "Worker_Reference": {"ID": "employee_id"},
  "Personal_Information": {
    "SSN": "123-45-6789"
  }
}

Complete Resolution Strategy:

Phase 1 - Inventory Existing SSNs:

  1. Extract all SSNs from Workday using the four API calls mentioned above
  2. Normalize all extracted SSNs (remove dashes, pad zeros, convert to 9-digit strings)
  3. Create a master exclusion list of SSNs already in Workday

Phase 2 - Enhanced Deduplication:

  1. Normalize all SSNs in your migration dataset using the same logic
  2. Flag placeholder SSNs (000-00-0000 patterns) for manual review
  3. Cross-reference migration SSNs against the Workday exclusion list
  4. For matches found: determine if it’s a rehire (same person) or true duplicate (different people, same SSN - data quality issue)

Phase 3 - Handle Legitimate Duplicates: For the ~200 cases where you’re migrating an active employee whose SSN exists on a terminated record:

  • If same person (rehire): Use the existing Worker_ID instead of creating new record
  • If different person (data error): Correct the SSN in source system before migration
  • If SSN must be preserved on terminated record (legal/compliance): Work with Workday support to temporarily clear terminated record’s SSN, migrate active employee, then restore if needed

Phase 4 - Resolve Unexplained Failures: For your remaining 300 failures without obvious Workday matches:

  1. Export these 300 SSNs and manually validate in source system
  2. Check for transposed digits (123-45-6789 vs 123-54-6789)
  3. Verify against contingent worker and applicant repositories
  4. Review Workday tenant’s custom validation rules (Security → Domain → National ID validations)

API Query to Find All SSN Instances:


GET /workers?Include_Terminated=true
GET /contingentWorkers
GET /jobApplications?status=all
Filter response for National_ID where Type='SSN'

The combination of incomplete worker type coverage, formatting inconsistencies, and placeholder SSNs in legacy data explains your 500 failures. Implementing the enhanced deduplication logic with comprehensive Workday inventory checking should reduce failures to less than 1% (representing genuine data quality issues requiring manual correction).

Be careful with SSN handling during migrations. Some organizations have data quality issues in legacy systems where the same SSN was accidentally assigned to multiple people, or placeholder SSNs like 000-00-0000 or 123-45-6789 were used for employees without SSNs. Your deduplication script should flag these patterns. Also verify your legacy system didn’t store SSNs with leading zeros that got stripped during export - 001-23-4567 becoming 1-23-4567 can cause mismatches.

Another possibility is SSN formatting inconsistencies. Even though you’ve standardized to XXX-XX-XXXX format, Workday stores SSNs without dashes internally. If your legacy data had some SSNs stored with dashes and others without, your deduplication script might have missed matches. Try normalizing by removing all dashes before comparison: 123-45-6789 and 123456789 are the same SSN but might not match in your deduplication logic.

Duplicate SSN errors during migration often relate to terminated employees that aren’t visible in standard searches. Workday retains SSNs for terminated workers indefinitely for compliance reasons. You need to use the Get_Workers API with the ‘Include Terminated’ parameter set to true to see all SSN values in the system. This will reveal the conflicts your scripts aren’t detecting.

I ran the Get_Workers call with terminated employees included and found about 200 matches - that explains part of the problem. However, I’m still seeing 300 failures where the SSN doesn’t appear in any active or terminated record. Could there be contingent workers or other worker types that aren’t returned by Get_Workers? Also, what’s the recommended approach for handling legitimate duplicates where we’re migrating an active employee but their SSN is already associated with a terminated record?

For the 300 unexplained failures, check if your Workday tenant has any custom validation rules on the SSN field. Some organizations implement additional SSN validation beyond Workday’s standard uniqueness check - like excluding certain SSN ranges or requiring SSN verification against external databases. These custom validations can cause API failures that aren’t obvious from the error message.

Yes, contingent workers are stored separately. Use Get_Contingent_Workers API in addition to Get_Workers. Also check for applicant records - if someone applied but wasn’t hired, their SSN might be in the recruiting module. For the legitimate duplicates with terminated workers, you’ll need to either clear the SSN from the terminated record first (if retention policy allows) or contact Workday support to merge the records if it’s actually the same person being rehired.