Tracker.Current.Session.IdentifyAs() will only merge contacts, if the current contact is not a known contact yet: Contact.IdentificationLevel != ContactIdentificationLevel.Known

If the current contact already is known, IdentifyAs() will not merge it with an existing contact that already has the identifier.

So what we ended up doing was this:

    public bool IdentifyAs(string source, string identifier)
    {
    	if (Tracker.Current == null)
    	{
    		return false;
    	}
    
    	// Contact already has the identifier
    	if (Tracker.Current.Session.Contact.Identifiers.Any(x => x.Source == source && x.Identifier == identifier))
    	{
    		return true;
    	}
    
    	var manager = Sitecore.Configuration.Factory.CreateObject("tracking/contactManager", true) as Sitecore.Analytics.Tracking.ContactManager;
    
    	if (manager == null)
    	{
    		Log.Error("XConnectContactRepository: Unable to instantiate ContactManager", this);
    		return false;
    	}
    
    	// Use default identifyAs for unknown contacts
    	if (Tracker.Current.Contact.IdentificationLevel != ContactIdentificationLevel.Known)
    	{
    		Tracker.Current.Session.IdentifyAs(source, identifier);
    
    		var contactId = Tracker.Current.Contact.ContactId;
    		manager.RemoveFromSession(contactId);
    		Tracker.Current.Session.Contact = manager.LoadContact(contactId);
    		return true;
    	}
    
    	var existingContact = manager.LoadContact(source, identifier);
    
    	// No other contact has this identifier yet: just set it
    	if (existingContact == null)
    	{
    		var contactId = Tracker.Current.Session.Contact.ContactId;
    
    		Log.Info($"Add identifier for contact '{contactId}'. {source} > {identifier}", this);
    
    		manager.AddIdentifier(contactId, new ContactIdentifier(source, identifier, ContactIdentificationLevel.Known));
    		manager.RemoveFromSession(contactId);
    		Tracker.Current.Session.Contact = manager.LoadContact(contactId);
    
    		return true;
    	}
    
    	// Other contact with identifier exists: Merge explicitly
    	var currentContact = Tracker.Current.Session.Contact;
    	var hasBehaviourProfiles = currentContact.BehaviorProfiles.Count != 0;
    
    	Log.Info($"Merge contacts '{currentContact.ContactId}' into {existingContact.ContactId}. reason: {source} > {identifier}", this);
    
    	Tracker.Current.Session.Contact = manager.MergeContacts(existingContact, currentContact);
    
    	manager.RemoveFromSession(Tracker.Current.Contact.ContactId);
    
    	Tracker.Current.Session.Interaction.ContactId = Tracker.Current.Session.Contact.ContactId;
    	Tracker.Current.Session.Interaction.ContactVisitIndex = Tracker.Current.Session.Contact.System.VisitCount;
    	
    	if (hasBehaviourProfiles || Tracker.Current.Interaction.Profiles.GetProfileNames().Length == 0)
    	{
    		InitializeInteractionProfilePipeline.Run(new InitializeInteractionProfileArgs(Tracker.Current.Session));
    	}
    
    	return true;
    }


We can now safely set multiple identifiers through our IdentifyAs():

    IdentifyAs("USERID_SOURCE", "U1542658"); 
    IdentifyAs("EMAIL_SOURCE", "[email protected]");