Documentation

User Offboarding Documentation

Transfer record ownership across your entire Salesforce org in one guided, auditable process. You do not need Apex, SOQL, or developer knowledge – everything here is done through the Lightning Experience interface.

Contents

1About This Guide

This guide explains how to use the User Offboarding application to reassign ownership of Salesforce records from one user to another. It is written for Salesforce administrators and anyone who has been granted the Ownership Transfer Manager permission set.

You do not need Apex, SOQL, or developer knowledge to use the app. Everything described here is performed through the Lightning Experience user interface.

Who should read this

  • Salesforce administrators handling employee departures, role changes, or territory reassignments.
  • Operations and HR-systems staff who own the offboarding checklist and need an auditable record of what moved.
  • Compliance reviewers who need to confirm that a departing user no longer owns records.

2What the App Does

Salesforce's native mass transfer tool works on one object at a time. If a departing user owns Accounts, Opportunities, Cases, Tasks, files, and records in a dozen custom objects, you have to repeat the same process for each one — and remember every object you need to check.

User Offboarding does this in a single pass. You pick the departing user and the new owner, and the application:

  1. Discovers every object automatically. It scans your org for every queryable object that has an updateable OwnerId field. There is no list to maintain.
  2. Lets you preview first. A Dry Run scans and reports exactly what would change, without touching a single record.
  3. Processes each object in its own batch. Large objects are chunked, so the job completes reliably regardless of record volume.
  4. Records everything. Each object produces a batch record with counts and per-record detail, and the whole job produces a downloadable CSV audit log.
  5. Tells you when it is done. You get an in-app notification and an email summary with a per-object breakdown.

3Before You Start

Requirements

RequirementDetail
Salesforce editionEnterprise, Unlimited, Performance, Developer, or Professional*
User interfaceLightning Experience (the app is desktop / large form factor)
PermissionOwnership Transfer Manager permission set assigned to your user
External servicesNone — the app is 100% native and your data never leaves Salesforce

* Professional Edition requires that the package's Apex is enabled; validate in a Professional Edition org before rolling out.

Pre-flight checklist

  • Confirm the target user is active and has the licences, profile access, and record access needed to own the incoming records.
  • Decide what must not move. Add any sensitive or system objects to the Restricted Objects list before you run (see section 10).
  • Check your Apex batch capacity. The job chains one batch per object, so run it outside of periods when other heavy batch jobs are queued.
  • Do not deactivate the departing user yet. Records can only be queried against an existing user; deactivate after the transfer has completed successfully.
  • Always run a Dry Run first, then review the results before committing to a Full Run.

4Setup and Access

Assign the permission set

Every user who will run transfers needs the Ownership Transfer Manager permission set. It grants the app, its tabs, its objects, and — critically — the Can Transfer Ownership custom permission that the application checks before it will start any job.

  1. From Setup, go to Users → Permission Sets.
  2. Open Ownership Transfer Manager.
  3. Click Manage Assignments, then Add Assignment.
  4. Select the users, and click Assign.

Open the app

  1. Click the App Launcher (the grid icon, top left).
  2. Search for and open User Offboarding.

The app opens on the User Offboarding home tab and provides three further tabs:

TabWhat it holds
User OffboardingThe home page — the welcome panel and the Start Ownership Transfer button.
Ownership Transfer JobsOne record per transfer request, with status, counts, and results.
Ownership Transfer BatchesOne record per object processed within a job, with per-record detail.
Restricted ObjectsThe exclusion list — objects that must never be transferred.
The User Offboarding home tab, with the welcome panel, the Start Ownership Transfer button, and the Active and Recent Jobs list view below it.
The home tab. The Active and Recent Jobs list view sits below the welcome panel.

5Understanding the Two Run Modes

Every job runs in one of two modes. You choose the mode when you start the job.

Dry RunFull Run
What it doesScans and counts onlyScans and reassigns ownership
Changes your dataNo — nothing is writtenYes — records are updated
Batch status shownScannedUpdated / Failed / Type Error
Counts reportedRecords FoundRecords Found, Updated, and Failed
CSV log producedYes (rows marked Scanned)Yes (rows marked Updated or Failed)
Typical usePreview and impact assessmentThe actual transfer

6Walkthrough: Running a Transfer

The recommended sequence is a Dry Run, a review, then a Full Run launched directly from the completed Dry Run job.

Step 1 — Start the job

  1. Open the User Offboarding app and stay on the home tab.
  2. Click Start Ownership Transfer.
  3. In Source User, search for and select the departing user. The app displays that user's username and email so you can confirm you have the right person.
  4. In Target User, search for and select the user who will receive the records. Their username and email are shown for confirmation too.
  5. Under Execution Mode, leave Dry Run (scan only, no changes) selected for your first pass.
  6. Click Start.

The Start button stays disabled until both users are selected. The source and target must be different users; choosing the same user for both produces an error.

Once started, you are taken straight to the new Ownership Transfer Job record, where the job runs in the background.

The Ownership Transfer form with Source User and Target User selected, each showing the username and email, and Execution Mode set to Dry Run.
Step 1. Each picker confirms the username and email so you can check you have the right person.

Step 2 — Review the Dry Run

Wait for the job's status to reach ✅ Completed, then review:

  • Objects Found — how many objects actually contained records owned by the source user.
  • Records Found — the total number of records that would be reassigned.
  • The Transfer Batches table — the per-object breakdown. Sort by Records Found to see where the volume is, or search for a specific object.
  • Open any batch record to see the individual records it identified.

This is the moment to add anything you do not want moved to the Restricted Objects list. Then start a fresh Dry Run so the preview reflects the exclusions.

Step 3 — Execute the Full Run

When a Dry Run job has completed, an Execute button appears next to the Status field on the job record.

  1. Click Execute.
  2. A confirmation dialog shows the source user, the target user, and the scan result — for example, Based on the scan: 1,482 records across 17 objects.
  3. Read the notice about re-scanning, then click Execute to confirm.

A new job record is created in Full Run mode and you are navigated to it. The original Dry Run job is left intact as a record of the preview.

A completed Dry Run job summary showing 97 objects total, 10 objects found, 113 records found, and the Execute button beside the Completed status.
Step 2 and 3. A completed Dry Run, with the Execute button beside the status.

7Monitoring a Running Job

The Ownership Transfer Job Summary panel at the top of the job record is your live view of progress. While the status is ⚡ Running, it shows:

FieldMeaning
StatusRunning, Stopped, or Completed
SummaryThe object currently being processed — e.g. Processing: Opportunity
DurationLive elapsed time, recalculated each time the panel renders
Objects TotalThe number of transferable objects discovered at job start
Objects ProcessedHow many of those have been handled so far
Objects FoundHow many objects actually contained records owned by the source user
Records FoundRunning total of records identified
Records UpdatedRunning total successfully reassigned (Full Run only)
Records FailedRunning total that could not be reassigned (Full Run only)

Objects Total will be much larger than Objects Found. Objects Total counts every object in your org that could hold owned records — typically several hundred. Objects Found counts only those where the source user actually owned something. A job that reports 4 objects found out of 612 total is working correctly.

8Reading the Results

The Transfer Batches table

Below the summary, the Transfer Batches table lists one row per object that contained records. It is searchable and every column is sortable.

ColumnMeaning
BatchThe batch record number (e.g. OTB-000123) — click to open the detail
ObjectThe object's friendly label, e.g. Opportunity
Object API NameThe API name, e.g. Opportunity or Project__c
StatusScanned, Updated, Failed, or Type Error
Records FoundRecords identified in this batch
Records UpdatedRecords successfully reassigned (Full Run only)
Records FailedRecords that could not be reassigned (Full Run only)

The Records Updated and Records Failed columns are hidden for Dry Run jobs, because nothing was updated.

Batch statuses

StatusWhat it meansWhat to do
📋 ScannedDry Run only. Records were identified; nothing was changed.Nothing — this is the expected Dry Run result.
✅ UpdatedEvery record in the batch was reassigned successfully.Nothing.
❌ FailedOne or more records could not be updated. The rest succeeded.Open the batch and read the per-record errors.
🚫 Type ErrorThe object cannot have its ownership transferred at all — usually because it inherits ownership from a parent record. The object is added to Restricted Objects automatically.No action needed. Future jobs will skip it.

The batch detail page

Opening a batch record shows the Process Execution Summary, which reports the object, a status message, and up to three tabs:

  • Found — records identified during a Dry Run, shown as clickable badges with the record's name.
  • Updated — records successfully reassigned during a Full Run.
  • Failures — a table of records that failed, each with its specific error message and a link to the record.

Tabs that would be empty are not displayed. Every record name links straight to the record, so you can inspect a failure without leaving the app.

A batch detail page showing the Process Execution Summary for the Account object with an Updated tab listing each reassigned record as a badge.
The batch detail page. Every record name links straight to the record.

9The Transfer Log CSV

When a job finishes, the app automatically generates a record-level CSV audit log and attaches it to the job record. Find it in the Files related list at the bottom of the job page, named Transfer_Log_<JobId>_0.csv.

Very large jobs are split across several files — _0, _1, _2, and so on. Download them all for the complete picture.

Columns in the CSV

ColumnContents
Log IDThe ID of the batch record this row came from
Initiated ByThe user who started the job
Source UserThe departing user
Target UserThe receiving user
Object API Namee.g. Opportunity
Object Labele.g. Opportunity
Record IDThe individual record's Salesforce ID
StatusScanned, Updated, or Failed
ErrorThe error message, for failed rows only

This file is the artefact to keep for compliance. It documents exactly which records changed hands, when, and at whose instruction.

10Restricted Objects

The Restricted Objects tab is your exclusion list. Any object listed there is skipped entirely — it is never scanned and never updated by any job.

Adding an exclusion manually

  1. Open the Restricted Objects tab.
  2. Click New.
  3. Enter the Object API Name exactly as Salesforce defines it — for example Case or Invoice__c. The match is exact and case-sensitive, so a typo silently does nothing.
  4. Optionally enter the Object Label and a Notes value explaining why the object is excluded.
  5. Click Save. The exclusion applies to the next job you start.
The Restricted Objects list view showing three excluded objects, each with a note explaining the exclusion.
The Restricted Objects tab, with a note recording why each object is excluded.

Entries the app adds by itself

When a Full Run discovers that an object cannot have its ownership changed at all — typically a detail object whose owner is inherited from its parent — it marks the batch as 🚫 Type Error and adds that object to Restricted Objects automatically, with the underlying error stored in Notes. Subsequent jobs skip it, so the list gets smarter with use.

ContentDocument is always excluded internally: transferring the ContentVersion moves the parent document as well, so processing both would be redundant.

Removing an exclusion

Delete the Restricted Object record. The object will be included again from the next job onward. Be careful when deleting entries the app created itself — they usually record a genuine platform limitation, and re-including such an object will simply produce the same errors again.

11What Gets Transferred (and What Does Not)

How objects are selected

At the start of every job, the app builds its own list of transferable objects. An object is included only when all of the following are true:

  • It is queryable in your org.
  • It is not on the Restricted Objects list.
  • It is accessible to the running user.
  • It has an OwnerId field.
  • That OwnerId field is both readable and updateable.

Everything else is skipped before the job even begins — which is why Objects Total is a much smaller number than the total object count in your org.

Objects with special handling

Some standard objects would reliably fail or cause unwanted side effects if transferred wholesale, so the app narrows what it selects for them:

ObjectOnly these records are transferred
Files (ContentVersion)The latest version of each file. The parent ContentDocument is reassigned at the same time, so files move intact.
TaskOpen tasks only. Closed tasks are historical and are left with the original owner.
EventNon-child events that are either in the future or part of a still-active recurring series. Past events are left alone.
QuoteQuotes that are not currently syncing with an opportunity.
OrderOrders that are not Activated.
ContractContracts that are not Activated.
Knowledge (Knowledge__kav)Draft articles only. Published and archived versions are not reassigned.

Why individual records can still fail

Even within a selected object, the platform can refuse an individual update. Common causes:

  • Locked records — records in an approval process cannot be edited.
  • Validation rules that reject the change, for example a rule requiring the owner to hold a particular role.
  • Assignment or territory rules that immediately re-route the record to a different owner.
  • Sharing and access limits — the target user may not be permitted to own the record.
  • Inherited ownership — detail records in a master-detail relationship take their owner from the parent.

Every one of these appears in the batch Failures tab with the platform's own error message, and in the CSV log with status Failed. Nothing fails silently.

12Stopping a Job

While a job is running, a Stop button appears next to the Status field on the job record.

  1. Click Stop.
  2. Read the confirmation dialog. It reports how far the job has got — for a Full Run it also tells you how many records have already been transferred.
  3. Click OK to confirm.

The job stops at the next safe point. Its status becomes 🛑 Stopped, and the summary records where it stopped — for example Job stopped by user while processing Opportunity. The CSV log and the completion email are still produced for the work that was done.

13Notifications and Email Summary

You do not have to watch a job to completion. When it finishes, the app notifies the user who started it in two ways.

In-app notification

A bell notification titled Ownership Transfer Completed appears on desktop and in the Salesforce mobile app. You will also receive a notification confirming the transfer report file has been generated.

Email summary

An email is sent to the user who started the job. It contains the job number, the source and target users, the start time, finish time, and duration, plus a table of every object where records were updated or failed, with the counts for each. A View Job Details button links straight back to the job record.

14Field Reference

Ownership Transfer Job

Record numbering: OTJ-0000. One record per transfer request.

FieldDescription
Initiated ByThe user who started the job
Source UserThe user whose records are being transferred away
Target UserThe user receiving the records
Mode🔍 Dry Run or ⚡ Full Run
Status⚡ Running, 🛑 Stopped, or ✅ Completed
SummaryLive progress message while running; the stop reason if stopped
Started At / Finished AtJob start and end timestamps
DurationFormatted elapsed time; shows Pending until the job finishes
Objects TotalTransferable objects discovered at job start
Objects ProcessedObjects handled so far
Objects FoundObjects that actually contained records owned by the source user
Records FoundTotal records identified
Records UpdatedTotal records successfully reassigned
Records FailedTotal records that could not be reassigned

Ownership Transfer Batch

Record numbering: OTB-000000. One or more records per object processed, linked to the parent job.

FieldDescription
Ownership Transfer JobsThe parent job
Object API NameAPI name of the object processed
Object LabelFriendly label of the object processed
Status📋 Scanned, ✅ Updated, ❌ Failed, or 🚫 Type Error
Records Found / Updated / FailedCounts for this batch
SummaryThe stored per-record detail rendered by the batch detail page

Restricted Object

Record numbering: RO-{0}. One record per excluded object.

FieldDescription
Object API NameThe exact API name to exclude — must match Salesforce precisely
Object LabelOptional friendly name, for readability
NotesWhy the object is excluded. Populated automatically with the platform error when the app adds an entry itself.

Useful list views

Each object ships with list views to help you find things quickly: Jobs offers All Jobs, Recent Jobs, Running Jobs, Completed Jobs, and Stopped Jobs; Batches offers All Batches, Updated Batches, Failed Batches, and Recent Failed Batches; Restricted Objects offers All Restricted Objects.

15Troubleshooting

SymptomCause and resolution
Access Denied: You do not have the "Can Transfer Ownership" permission assigned to your user.Your user is missing the Can Transfer Ownership custom permission. Assign the Ownership Transfer Manager permission set (section 4).
Both source and target user must be selected.One of the pickers is empty. Select both users and try again.
Source and target users should be different.You selected the same user twice. Choose a different target user.
You do not have permission to stop this job.Your user cannot edit the job's Status field. Confirm the permission set is assigned and has not been modified.
The Start button stays greyed outBoth Source User and Target User must be selected before the button enables.
Objects Total is in the hundredsThis is expected. It counts every object that could hold owned records. Look at Objects Found for the meaningful number.
A whole object shows 🚫 Type ErrorThe object inherits ownership from a parent and cannot be transferred directly. The app has added it to Restricted Objects; no action is needed.
Records Failed is high for one objectOpen the batch and read the Failures tab. Validation rules, locked records, and assignment rules are the usual causes.
Full Run moved a different number of records than the Dry Run predictedExpected. The Full Run re-scans from scratch, so any data that changed between the two runs is reflected in the new result.
Counts do not appear to be updatingThe summary panel does not poll automatically. Click Refresh.
No CSV file on the job recordThe file is generated after the transfer completes; allow a moment and refresh. If the job found no records at all, no file is produced.
No completion emailCheck Setup → Email → Deliverability is set to All email. Sandboxes and scratch orgs commonly restrict it.
Job appears stuck as ⚡ RunningCheck Setup → Apex Jobs. The job chains one Apex batch per object, so a queue backlog or a hit flex-queue limit can delay it. Job records are not left Running once the chain completes.

16Frequently Asked Questions

Can I undo a transfer?

Not from within the app. There is no rollback. This is precisely why the Dry Run mode exists — preview first, every time. If you must reverse a transfer, you can run a new job in the opposite direction, but be aware that it will move every record the second user now owns, not only the ones you just transferred. The CSV log gives you the exact record IDs if you need a targeted correction.

Do I have to deactivate the departing user first?

No — and you should not. Run the transfer while the user is still active, confirm the results, then deactivate.

Can I transfer only certain objects?

Yes, indirectly. Add every object you do not want moved to the Restricted Objects list. The app always processes all remaining transferable objects; there is no per-job object picker.

Can I run two jobs at the same time?

The app does not prevent it, but it is not advisable. Each job chains one Apex batch per object, and concurrent jobs compete for the same Apex batch capacity. Run them one after another.

Does this move files and attachments?

Yes. Files are transferred via ContentVersion, and the parent ContentDocument is reassigned at the same time, so files move intact rather than being orphaned.

Why were closed tasks and past events left behind?

By design. Closed activities are historical records, and reassigning them misrepresents who did the work. Only open tasks and current or future events are transferred.

What happens to records the target user cannot access?

The update fails and the record is logged with the platform's error message. Confirm the target user's profile, role, and sharing access before the Full Run.

Is any data sent outside my org?

No. The application is 100% native. All processing happens inside Salesforce and no external service is called.

Can I start a transfer from a Flow?

Yes. The app exposes a Transfer Record Ownership invocable action taking a source user ID, a target user ID, and a dry-run flag. It processes one request at a time — bulk invocation is not supported.

How long will a job take?

It depends on the number of objects in your org and the record volume. The job processes objects one at a time in chained Apex batches, so a large org can take a while. You do not need to watch it — you will be notified when it finishes.