diff --git a/src/db/models/user.rs b/src/db/models/user.rs
index c553fd0e..917ea61e 100644
--- a/src/db/models/user.rs
+++ b/src/db/models/user.rs
@@ -1,6 +1,7 @@
 use crate::util::{format_date, get_uuid, retry};
 use chrono::{NaiveDateTime, TimeDelta, Utc};
 use serde_json::Value;
+use std::cmp::Ordering;
 
 use crate::crypto;
 use crate::CONFIG;
@@ -487,7 +488,8 @@ impl SsoUser {
     }
 
     // Written as an union to make the query more lisible than using an `or_filter`.
-    // But `first()` does not appear to work with `union()` so we use `load()`.
+    // If there is a match on identifier and email we want the identifier match.
+    // We sort results in code since UNION does not garanty order and DBs order NULL differently.
     pub async fn find_by_identifier_or_email(
         identifier: &str,
         mail: &str,
@@ -496,7 +498,7 @@ impl SsoUser {
         let lower_mail = mail.to_lowercase();
 
         db_run! {conn: {
-            users::table
+            let mut res = users::table
                 .inner_join(sso_users::table)
                 .select(<(UserDb, Option<SsoUserDb>)>::as_select())
                 .filter(sso_users::identifier.eq(identifier))
@@ -509,8 +511,17 @@ impl SsoUser {
                 .load(conn)
                 .expect("Error searching user by SSO identifier and email")
                 .into_iter()
-                .next()
                 .map(|(user, sso_user)| { (user.from_db(), sso_user.from_db()) })
+                .collect::<Vec<(User, Option<SsoUser>)>>();
+
+            res.sort_by(|(_, sso_user), _| {
+                match sso_user {
+                    Some(db_sso_user) if db_sso_user.identifier == identifier => Ordering::Less,
+                    _ => Ordering::Greater,
+                }
+            });
+
+            res.into_iter().next()
         }}
     }
 }