diff --git a/django/db/models/expressions.py b/django/db/models/expressions.py
index 16df317631..36f88f99ec 100644
--- a/django/db/models/expressions.py
+++ b/django/db/models/expressions.py
@@ -286,8 +286,15 @@ class BaseExpression:
         """
         sources_iter = (source for source in self.get_source_fields() if source is not None)
         for output_field in sources_iter:
-            if any(not isinstance(output_field, source.__class__) for source in sources_iter):
-                raise FieldError('Expression contains mixed types. You must set output_field.')
+            for source in sources_iter:
+                if not isinstance(output_field, source.__class__):
+                    raise FieldError(
+                        'Expression contains mixed types: %s, %s. You must '
+                        'set output_field.' % (
+                            output_field.__class__.__name__,
+                            source.__class__.__name__,
+                        )
+                    )
             return output_field
 
     @staticmethod
diff --git a/tests/aggregation/tests.py b/tests/aggregation/tests.py
index a336758f45..bd6ecf699c 100644
--- a/tests/aggregation/tests.py
+++ b/tests/aggregation/tests.py
@@ -884,7 +884,10 @@ class AggregateTestCase(TestCase):
         self.assertEqual(p2, {'avg_price': Approximate(Decimal('53.39'), places=2)})
 
     def test_combine_different_types(self):
-        msg = 'Expression contains mixed types. You must set output_field.'
+        msg = (
+            'Expression contains mixed types: FloatField, IntegerField. '
+            'You must set output_field.'
+        )
         qs = Book.objects.annotate(sums=Sum('rating') + Sum('pages') + Sum('price'))
         with self.assertRaisesMessage(FieldError, msg):
             qs.first()