Yes — you can create a Lookup relationship on an object that already has data, with no restrictions. Existing records simply have the new lookup field empty (null). Salesforce does not check that every row references something — Lookup is, by default, optional, and even when marked Required it only enforces the constraint on new and edited records going forward, not on existing ones (until they’re edited).
This is one of the key differences between Lookup and Master-Detail.
What happens when you add a lookup to a populated object
- The new field is created with a default value of null on all existing records.
- The related list automatically appears on the parent (subject to page layout config).
- Reports, list views, and SOQL immediately recognize the field.
- Users can populate it manually, via data loader, via flow, or via integration.
If the lookup is marked Required:
- New record creation must supply a value, or save fails.
- Existing records with null values stay null until someone edits them — at which point the user must supply a value before save.
This is the platform being pragmatic: a strict “must-have-value” rule is enforced going forward but doesn’t break what’s already there.
Compare to Master-Detail
For master-detail, Salesforce blocks creation of the field if any existing record would end up without a parent. You’d see an error like “Cannot create relationship: object has existing records.” The fix is the well-known lookup → master-detail conversion pattern:
- Add the field as a Lookup first.
- Backfill the lookup value on every existing record (data loader, flow, mass update tool).
- Verify zero nulls remain.
- Convert the field to Master-Detail.
Step 4 fails if any record still has a null. Once every row has a parent, the conversion succeeds.
Practical scenario
“You inherited an org with 50,000 existing
Project__crecords and now need to relate them to a newCustomer__cobject.”
Plan:
- Create
Customer__cand load customer data. - On
Project__c, add a Lookup fieldCustomer__c→Customer__c. (No error — existing data is fine.) - Use a flow or Apex script to populate
Project__c.Customer__cfrom existing data (perhaps matching on Account name, customer code, or a manual mapping table). - Run reports to check coverage; clean up the unmapped rows manually.
- If business rules say every project must have a customer, mark the field Required at this point.
- If you want roll-up summaries on Customer, convert to Master-Detail (only safe after step 4).
Things to watch out for
- Bulk edits: If you mark the lookup Required, users who edit a record without setting the lookup will hit validation. Plan a remediation window before flipping the switch.
- Validation rules: Existing validation rules referencing the new field will evaluate against null until populated — review them for unexpected NPE-like behavior.
- Reports: Reports filtering on the new field need to handle “is null” explicitly during transition.
- Integrations: Outbound integrations that consumed the parent record may now expect the new field — coordinate before adding.
Quick summary table
| Action | Allowed on object with data? | Notes |
|---|---|---|
| Add Lookup (optional) | Yes — always | Existing records null until edited |
| Add Lookup (required) | Yes — but applies only going forward | Existing nulls allowed; future edits must populate |
| Add Master-Detail | No — blocked if any existing records | Use lookup → backfill → convert pattern |
| Convert Lookup → Master-Detail | Only if zero nulls in the lookup | Strict pre-flight check |
| Convert Master-Detail → Lookup | Yes; must first delete dependent roll-ups | Reverse of above |
Verified against: Salesforce Help — Lookup Relationship Considerations. Last reviewed 2026-05-17.