Contacts are created in a variety of ways. One of them is Synchronization of User / Lead / Contact through MC Connect.
Other ways exist and it's impossible from the outside to determine the root cause. What can be generalized is how you can try to find patterns in your Contact Keys / work with the actual data to narrow this down.
- Pull up Mobile Studio.
- Create a filtered list with filter on System Data > Contacts > create a filtered list
- Set as filter: ContactKey Is Not empty.
- save this as a list called, e.g. "allContactsCopy".
This list is compatible with SQL which gives you the best tool to check what's actually in your data.
That approach is documented here: https://help.salesforce.com/s/articleView?id=000313920&type=1
Use sql to dig into your Contacts:
- These are all contacts that are coming from SF Contacts (synchronized / through journeys or through sends to SF campaigns and reports):
SELECT
subscriberKey
FROM allContactsCopy
WHERE subscriberKey LIKE '003%'
Edit: of course this does not say that these contacts are really still in your connected SF Org! The SFMC system could have been connected to another org or a sandbox in the past. So compare them to the Contacts you actually have in SF.
- these are all contacts that are coming from SF Leads (same as above):
SELECT
subscriberKey
FROM allContactsCopy
WHERE subscriberKey LIKE '00Q%'
- these are all contacts whose subscriberKey is an Email address (e.g. someone imported a list from somewhere and sent to these addresses using email as subscriberkey; someone set up an external triggered send / transactional interface and used email as contactKey)
SELECT
subscriberKey
FROM allContactsCopy
WHERE subscriberKey LIKE '%@%'
... and so forth, you get the idea.
if you use mobilePush or SMS, that's another potential source; see if you can determine Contacts where keys look like mobile numbers
Also, run a query that returns everything BUT the above, then you get the less-obvious "residue".
Of course you can do more than just look at the patterns behind the IDs but focus more on "where do they come from" -
E.g.:
- Run the export to get "contacts without channel address", reimport them somewhere - compare the extract with your "allContactsCopy".
https://help.salesforce.com/s/articleView?language=en_US&type=5&id=sf.mc_rn_may_2020_cab_extract_contacts_without_channel_address.htm
compare your list against the _subscribers Data view.
verify your sendable DEs and check what send relationship is set - What's in this field becomes the Contact Id at time of send (unless it's already a contact)
check your journeys that are called from SF / external sources via API;
check triggered sends
this should give you a much better level of granularity than just looking at numbers.