diff --git a/addons/mail/models/mail_thread_blacklist.py b/addons/mail/models/mail_thread_blacklist.py
index c7c32fc1b4f49d34e613e4f8852fe4db316720e5..a1eed2714bf90d49c56e5773c54042b5c80bacff 100644
--- a/addons/mail/models/mail_thread_blacklist.py
+++ b/addons/mail/models/mail_thread_blacklist.py
@@ -47,7 +47,7 @@ class MailBlackListMixin(models.AbstractModel):
     def _compute_email_normalized(self):
         self._assert_primary_email()
         for record in self:
-            record.email_normalized = tools.email_normalize(record[self._primary_email])
+            record.email_normalized = tools.email_normalize(record[self._primary_email], strict=False)
 
     @api.model
     def _search_is_blacklisted(self, operator, value):
diff --git a/addons/mail/tests/test_mail_tools.py b/addons/mail/tests/test_mail_tools.py
index 7682331e70d65e39ae0c241f461ced78e3a5f626..cc0313f9a9f9bba339375d30dce1fc151420d5a8 100644
--- a/addons/mail/tests/test_mail_tools.py
+++ b/addons/mail/tests/test_mail_tools.py
@@ -158,7 +158,7 @@ class TestMailTools(MailCommon):
             (f'{self._test_email}, {_test_email_2}', True),  # multi-email, both matching, depends on comparison
             (f'{self._test_email}, {_test_email_2}', False)  # multi-email, both matching, depends on comparison
         ]
-        expected = [self.env['res.partner'], self.env['res.partner'],
+        expected = [follower_partner, test_partner,
                     self.env['res.partner'], self.env['res.partner'],
                     self.env['res.partner'], self.env['res.partner'],
                     self.env['res.partner'], self.env['res.partner']]
diff --git a/addons/mail/tests/test_res_partner.py b/addons/mail/tests/test_res_partner.py
index 13fbb8313745588d6ac77a9c2f48c7ef746c249a..9cb035c47b648ea21c3e16c5da0efac5d7caefd4 100644
--- a/addons/mail/tests/test_res_partner.py
+++ b/addons/mail/tests/test_res_partner.py
@@ -126,9 +126,11 @@ class TestPartner(MailCommon):
              '"FindMe Format" <find.me.format@test.example.com>',
              '"FindMe Multi" <find.me.multi.1@test.example.com,find.me.multi.2@test.example.com>']
         )
+        # when having multi emails, first found one is taken as normalized email
         self.assertEqual(
             partners.mapped('email_normalized'),
-            ['classic.format@test.example.com', 'find.me.format@test.example.com', False]
+            ['classic.format@test.example.com', 'find.me.format@test.example.com',
+             'find.me.multi.1@test.example.com']
         )
 
         # classic find or create: use normalized email to compare records
@@ -140,11 +142,18 @@ class TestPartner(MailCommon):
             with self.subTest(email=email):
                 self.assertEqual(self.env['res.partner'].find_or_create(email), partners[1])
         # multi-emails -> no normalized email -> fails each time, create new partner (FIXME)
-        for email in ('find.me.multi.1@test.example.com', 'find.me.multi.2@test.example.com'):
-            with self.subTest(email=email):
-                partner = self.env['res.partner'].find_or_create(email)
-                self.assertNotIn(partner, partners)
-                self.assertEqual(partner.email, email)
+        for email_input, match_partner in [
+            ('find.me.multi.1@test.example.com', partners[2]),
+            ('find.me.multi.2@test.example.com', self.env['res.partner']),
+        ]:
+            with self.subTest(email_input=email_input):
+                partner = self.env['res.partner'].find_or_create(email_input)
+                # either matching existing, either new partner
+                if match_partner:
+                    self.assertEqual(partner, match_partner)
+                else:
+                    self.assertNotIn(partner, partners)
+                    self.assertEqual(partner.email, email_input)
                 partner.unlink()  # do not mess with subsequent tests
 
         # now input is multi email -> '_parse_partner_name' used in 'find_or_create'
diff --git a/addons/test_mail/tests/test_mail_composer.py b/addons/test_mail/tests/test_mail_composer.py
index 7c7e14f3a5462b052e0ca2be5ea94ee8ae826f54..c346726d0980a7bf593169b18f5f391bfbdfd1df 100644
--- a/addons/test_mail/tests/test_mail_composer.py
+++ b/addons/test_mail/tests/test_mail_composer.py
@@ -1385,15 +1385,14 @@ class TestComposerResultsComment(TestMailComposer):
         # FIXME: currently email finding based on formatted / multi emails does
         # not work
         new_partners = self.env['res.partner'].search([]).search([('id', 'not in', existing_partners.ids)])
-        self.assertEqual(len(new_partners), 9,
-                         'Mail (FIXME): multiple partner creation due to formatted / multi emails: 2 extra partners')
+        self.assertEqual(len(new_partners), 8,
+                         'Mail (FIXME): multiple partner creation due to formatted / multi emails: 1 extra partners')
         self.assertIn(partner_format_tofind, new_partners)
         self.assertIn(partner_multi_tofind, new_partners)
         self.assertEqual(
             sorted(new_partners.mapped('email')),
             sorted(['"FindMe Format" <find.me.format@test.example.com>',
                     'find.me.multi.1@test.example.com, "FindMe Multi" <find.me.multi.2@test.example.com>',
-                    'find.me.multi.1@test.example.com',
                     'find.me.multi.2@test.example.com',
                     'test.cc.1@example.com', 'test.cc.2@example.com', 'test.cc.2.2@example.com',
                     'test.to.1@example.com', 'test.to.2@example.com']),
@@ -1403,7 +1402,6 @@ class TestComposerResultsComment(TestMailComposer):
             sorted(new_partners.mapped('email_formatted')),
             sorted(['"FindMe Format" <find.me.format@test.example.com>',
                     '"FindMe Multi" <find.me.multi.1@test.example.com,find.me.multi.2@test.example.com>',
-                    '"find.me.multi.1@test.example.com" <find.me.multi.1@test.example.com>',
                     '"find.me.multi.2@test.example.com" <find.me.multi.2@test.example.com>',
                     '"test.cc.1@example.com" <test.cc.1@example.com>',
                     '"test.cc.2@example.com" <test.cc.2@example.com>',
@@ -1415,7 +1413,6 @@ class TestComposerResultsComment(TestMailComposer):
             sorted(new_partners.mapped('name')),
             sorted(['FindMe Format',
                     'FindMe Multi',
-                    'find.me.multi.1@test.example.com',
                     'find.me.multi.2@test.example.com',
                     'test.cc.1@example.com', 'test.to.1@example.com', 'test.to.2@example.com',
                     'test.cc.2@example.com', 'test.cc.2.2@example.com']),
@@ -1429,14 +1426,10 @@ class TestComposerResultsComment(TestMailComposer):
         # FIXME: more partners created than real emails (see above) -> due to
         #   transformation from email -> partner in template 'generate_recipients'
         #   there are more partners than email to notify;
-        # NOTE: 'Findme Multi' is excluded as it has the same email as 'find.me.multi.1@test.example.com'
-        #   (created by template) and comes second in a search based on email
-        mailed_new_partners = new_partners.filtered(lambda p: p.name != 'FindMe Multi')
-        self.assertEqual(len(mailed_new_partners), 8)
         self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail')
         self.assertEqual(
-            len(self._mails), len(mailed_new_partners) + 3,
-            f'Should have sent {len(mailed_new_partners) + 3} emails, one / recipient ({len(mailed_new_partners)} mailed partners + partner_1 + partner_2 + partner_employee)')
+            len(self._mails), len(new_partners) + 3,
+            f'Should have sent {len(new_partners) + 3} emails, one / recipient ({len(new_partners)} mailed partners + partner_1 + partner_2 + partner_employee)')
         self.assertMailMail(
             self.partner_employee_2, 'sent',
             author=self.partner_employee,
@@ -1453,12 +1446,14 @@ class TestComposerResultsComment(TestMailComposer):
             mail_message=self.test_record.message_ids[0],
         )
         self.assertMailMail(
-            self.partner_1 + self.partner_2 + mailed_new_partners, 'sent',
+            self.partner_1 + self.partner_2 + new_partners, 'sent',
             author=self.partner_employee,
             email_to_recipients=[
                 [self.partner_1.email_formatted],
                 [f'"{self.partner_2.name}" <valid.other.1@agrolait.com>', f'"{self.partner_2.name}" <valid.other.cc@agrolait.com>'],
-            ] + [[email] for email in mailed_new_partners.mapped('email_formatted')],
+            ] + [[new_partners[0]['email_formatted']],
+                 ['"FindMe Multi" <find.me.multi.1@test.example.com>', '"FindMe Multi" <find.me.multi.2@test.example.com>']
+            ] + [[email] for email in new_partners[2:].mapped('email_formatted')],
             email_values={
                 'body_content': f'TemplateBody {self.test_record.name}',
                 # single email event if email field is multi-email
@@ -1958,15 +1953,14 @@ class TestComposerResultsMass(TestMailComposer):
         # FIXME: currently email finding based on formatted / multi emails does
         # not work
         new_partners = self.env['res.partner'].search([]).search([('id', 'not in', existing_partners.ids)])
-        self.assertEqual(len(new_partners), 9,
-                         'Mail (FIXME): did not find existing partners for formatted / multi emails: 2 extra partners')
+        self.assertEqual(len(new_partners), 8,
+                         'Mail (FIXME): did not find existing partners for formatted / multi emails: 1 extra partners')
         self.assertIn(partner_format_tofind, new_partners)
         self.assertIn(partner_multi_tofind, new_partners)
         self.assertEqual(
             sorted(new_partners.mapped('email')),
             sorted(['"FindMe Format" <find.me.format@test.example.com>',
                     'find.me.multi.1@test.example.com, "FindMe Multi" <find.me.multi.2@test.example.com>',
-                    'find.me.multi.1@test.example.com',
                     'find.me.multi.2@test.example.com',
                     'test.cc.1@example.com', 'test.cc.2@example.com', 'test.cc.2.2@example.com',
                     'test.to.1@example.com', 'test.to.2@example.com']),
@@ -1976,7 +1970,6 @@ class TestComposerResultsMass(TestMailComposer):
             sorted(new_partners.mapped('email_formatted')),
             sorted(['"FindMe Format" <find.me.format@test.example.com>',
                     '"FindMe Multi" <find.me.multi.1@test.example.com,find.me.multi.2@test.example.com>',
-                    '"find.me.multi.1@test.example.com" <find.me.multi.1@test.example.com>',
                     '"find.me.multi.2@test.example.com" <find.me.multi.2@test.example.com>',
                     '"test.cc.1@example.com" <test.cc.1@example.com>',
                     '"test.cc.2@example.com" <test.cc.2@example.com>',
@@ -1988,7 +1981,6 @@ class TestComposerResultsMass(TestMailComposer):
             sorted(new_partners.mapped('name')),
             sorted(['FindMe Format',
                     'FindMe Multi',
-                    'find.me.multi.1@test.example.com',
                     'find.me.multi.2@test.example.com',
                     'test.cc.1@example.com', 'test.to.1@example.com', 'test.to.2@example.com',
                     'test.cc.2@example.com', 'test.cc.2.2@example.com']),
@@ -2003,23 +1995,21 @@ class TestComposerResultsMass(TestMailComposer):
         # FIXME: more partners created than real emails (see above) -> due to
         #   transformation from email -> partner in template 'generate_recipients'
         #   there are more partners than email to notify;
-        # NOTE: 'Findme Multi' is excluded as it has the same email as 'find.me.multi.1@test.example.com'
-        #   (created by template) and comes second in a search based on email
-        mailed_new_partners = new_partners.filtered(lambda p: p.name != 'FindMe Multi')
-        self.assertEqual(len(mailed_new_partners), 8)
         self.assertEqual(len(self._new_mails), 2, 'Should have created 2 mail.mail')
         self.assertEqual(
-            len(self._mails), (len(mailed_new_partners) + 2) * 2,
-            f'Should have sent {(len(mailed_new_partners) + 2) * 2} emails, one / recipient ({len(mailed_new_partners)} mailed partners + partner_1 + partner_2) * 2 records')
+            len(self._mails), (len(new_partners) + 2) * 2,
+            f'Should have sent {(len(new_partners) + 2) * 2} emails, one / recipient ({len(new_partners)} mailed partners + partner_1 + partner_2) * 2 records')
         for record in self.test_records:
             self.assertMailMail(
-                self.partner_1 + self.partner_2 + mailed_new_partners,
+                self.partner_1 + self.partner_2 + new_partners,
                 'sent',
                 author=self.partner_employee,
                 email_to_recipients=[
                     [self.partner_1.email_formatted],
                     [f'"{self.partner_2.name}" <valid.other.1@agrolait.com>', f'"{self.partner_2.name}" <valid.other.cc@agrolait.com>'],
-                ] + [[email] for email in mailed_new_partners.mapped('email_formatted')],
+                ] + [[new_partners[0]['email_formatted']],
+                     ['"FindMe Multi" <find.me.multi.1@test.example.com>', '"FindMe Multi" <find.me.multi.2@test.example.com>']
+                ] + [[email] for email in new_partners[2:].mapped('email_formatted')],
                 email_values={
                     'body_content': f'TemplateBody {record.name}',
                     # single email event if email field is multi-email
diff --git a/addons/test_mail/tests/test_mail_gateway.py b/addons/test_mail/tests/test_mail_gateway.py
index a587059d675e39adcc4af7f3654afdd85c52e56c..74ca6b91179acd4dc2afcc09bc35d4a8621ce1d0 100644
--- a/addons/test_mail/tests/test_mail_gateway.py
+++ b/addons/test_mail/tests/test_mail_gateway.py
@@ -486,8 +486,8 @@ class TestMailgateway(TestMailCommon):
             record = self.format_and_process(
                 MAIL_TEMPLATE, f'"Valid Lelitre" <{test_email}>', 'groups@test.com', subject='Test3')
 
-        self.assertFalse(record.message_ids[0].author_id,
-                         'message_process (FIXME): unrecognized email -> author_id due to multi email')
+        self.assertEqual(record.message_ids[0].author_id, self.partner_1,
+                         'message_process: found author based on first found email normalized, even with multi emails')
         self.assertEqual(record.message_ids[0].email_from, f'"Valid Lelitre" <{test_email}>')
         self.assertNotSentEmail()  # No notification / bounce should be sent
 
@@ -496,8 +496,8 @@ class TestMailgateway(TestMailCommon):
             record = self.format_and_process(
                 MAIL_TEMPLATE, test_email, 'groups@test.com', subject='Test4')
 
-        self.assertFalse(record.message_ids[0].author_id,
-                         'message_process (FIXME): unrecognized email -> author_id due to multi email')
+        self.assertEqual(record.message_ids[0].author_id, self.partner_1,
+                         'message_process: found author based on first found email normalized, even with multi emails')
         self.assertEqual(record.message_ids[0].email_from, test_email)
         self.assertNotSentEmail()  # No notification / bounce should be sent
 
@@ -717,7 +717,7 @@ class TestMailgateway(TestMailCommon):
 
         for partner_email, passed in [
             (formataddr((self.partner_1.name, self.partner_1.email_normalized)), True),
-            (f'{self.partner_1.email_normalized}, "Multi Email" <multi.email@test.example.com>', False),
+            (f'{self.partner_1.email_normalized}, "Multi Email" <multi.email@test.example.com>', True),
             (f'"Multi Email" <multi.email@test.example.com>, {self.partner_1.email_normalized}', False),
         ]:
             with self.subTest(partner_email=partner_email):
diff --git a/addons/test_mail/tests/test_mail_thread_mixins.py b/addons/test_mail/tests/test_mail_thread_mixins.py
index 5588a6ffb79f324926e3a5be5166a9e00ccf62d6..fb2c2e203cedd4e06fe9f78120e78132da0dec5d 100644
--- a/addons/test_mail/tests/test_mail_thread_mixins.py
+++ b/addons/test_mail/tests/test_mail_thread_mixins.py
@@ -29,9 +29,9 @@ class TestMailThread(TestMailCommon, TestRecipients):
                       (' ', False)]
         multi_pairs = [
             (f'{base_email}, other.email@test.example.com',
-             False),  # multi not supported currently
+             base_email),  # multi supports first found
             (f'{tools.formataddr(("Another Name", base_email))}, other.email@test.example.com',
-             False),  # multi not supported currently
+             base_email),  # multi supports first found
         ]
         for email_from, exp_email_normalized in valid_pairs + void_pairs + multi_pairs:
             with self.subTest(email_from=email_from, exp_email_normalized=exp_email_normalized):
diff --git a/addons/test_mass_mailing/tests/test_mailing.py b/addons/test_mass_mailing/tests/test_mailing.py
index 91d6f71495b48b23a3b8a7f18019040b05209f58..899b4eb502dabb433f6cda9cfe3ddde0d251d0eb 100644
--- a/addons/test_mass_mailing/tests/test_mailing.py
+++ b/addons/test_mass_mailing/tests/test_mailing.py
@@ -207,6 +207,8 @@ class TestMassMailing(TestMassMailCommon):
                 # as it uses email_normalized if possible
                 if dst_model == 'mailing.test.customer':
                     formatted_mailmail_email = '"Formatted Record" <record.format@example.com>'
+                    multi_mail_mail_email = 'record.multi.1@example.com, "Record Multi 2" <record.multi.2@example.com>'
+                    multi_outgoing_emails = ['record.multi.1@example.com', '"Record Multi 2" <record.multi.2@example.com>']
                     unicode_email = '"Unicode Record" <record.😊@example.com>'
                     unicode_mailmail_email = '"Unicode Record" <record.😊@example.com>'
                     record_case_email = 'TEST.RECORD.CASE@EXAMPLE.COM'
@@ -217,6 +219,8 @@ class TestMassMailing(TestMassMailCommon):
                 else:
                     formatted_mailmail_email = 'record.format@example.com'
                     unicode_email = 'record.😊@example.com'
+                    multi_mail_mail_email = 'record.multi.1@example.com'
+                    multi_outgoing_emails = ['record.multi.1@example.com']
                     unicode_mailmail_email = 'record.😊@example.com'
                     record_case_email = 'test.record.case@example.com'
                     record_weird_email = 'test.record.weird@example.comweirdformat'
@@ -258,8 +262,8 @@ class TestMassMailing(TestMassMailCommon):
                          'partner': customer_weird_2,
                          'trace_status': 'sent'},
                         {'email': 'record.multi.1@example.com',
-                         'email_to_mail': 'record.multi.1@example.com, "Record Multi 2" <record.multi.2@example.com>',
-                         'email_to_recipients': [['record.multi.1@example.com', '"Record Multi 2" <record.multi.2@example.com>']],
+                         'email_to_mail': multi_mail_mail_email,
+                         'email_to_recipients': [multi_outgoing_emails],
                          'failure_type': False,
                          'trace_status': 'sent'},
                         {'email': 'record.format@example.com',
diff --git a/odoo/addons/base/tests/test_mail.py b/odoo/addons/base/tests/test_mail.py
index e4f1902765b1c3460425b723d18341dafc27d39d..a2bd023d7e6a83c344bfc429aae3ec130179621a 100644
--- a/odoo/addons/base/tests/test_mail.py
+++ b/odoo/addons/base/tests/test_mail.py
@@ -440,7 +440,7 @@ class TestEmailTools(BaseCase):
         ]
         for source, expected in zip(sources, expected_list):
             with self.subTest(source=source):
-                self.assertEqual(email_normalize(source), expected)
+                self.assertEqual(email_normalize(source, strict=True), expected)
 
     def test_email_split(self):
         """ Test 'email_split' """
diff --git a/odoo/tools/mail.py b/odoo/tools/mail.py
index ce5544ca10fe21d20eb47e006b8888b391d1fc48..720344aecf6ff848b18016b0fde59093797f6203 100644
--- a/odoo/tools/mail.py
+++ b/odoo/tools/mail.py
@@ -560,8 +560,11 @@ def email_normalize(text, strict=True):
         - Possible Input Email : 'Name <NaMe@DoMaIn.CoM>'
         - Normalized Output Email : 'name@domain.com'
 
-    :param bool strict: text should contain exactly one email (default behavior
-      and unique behavior before Odoo16);
+    :param boolean strict: if True, text should contain a single email
+      (default behavior in stable 14+). If more than one email is found no
+      normalized email is returned. If False the first found candidate is used
+      e.g. if email is 'tony@e.com, "Tony2" <tony2@e.com>', result is either
+      False (strict=True), either 'tony@e.com' (strict=False).
 
     :return: False if no email found (or if more than 1 email found when being
       in strict mode); normalized email otherwise;