diff --git a/django/middleware/common.py b/django/middleware/common.py
index 6fbbf43044..ccc9fbfaad 100644
--- a/django/middleware/common.py
+++ b/django/middleware/common.py
@@ -6,6 +6,7 @@ from django.conf import settings
 from django import http
 from django.core.mail import mail_managers
 from django.utils.http import urlquote
+from django.utils import six
 from django.core import urlresolvers
 
 
@@ -87,7 +88,17 @@ class CommonMiddleware(object):
         else:
             newurl = urlquote(new_url[1])
         if request.META.get('QUERY_STRING', ''):
-            newurl += '?' + request.META['QUERY_STRING']
+            if six.PY3:
+                newurl += '?' + request.META['QUERY_STRING']
+            else:
+                # `query_string` is a bytestring. Appending it to the unicode
+                # string `newurl` will fail if it isn't ASCII-only. This isn't
+                # allowed; only broken software generates such query strings.
+                # Better drop the invalid query string than crash (#15152).
+                try:
+                    newurl += '?' + request.META['QUERY_STRING'].decode()
+                except UnicodeDecodeError:
+                    pass
         return http.HttpResponsePermanentRedirect(newurl)
 
     def process_response(self, request, response):
diff --git a/tests/regressiontests/middleware/tests.py b/tests/regressiontests/middleware/tests.py
index de901f4a80..b8cffd9c92 100644
--- a/tests/regressiontests/middleware/tests.py
+++ b/tests/regressiontests/middleware/tests.py
@@ -294,6 +294,15 @@ class CommonMiddlewareTest(TestCase):
         CommonMiddleware().process_response(request, response)
         self.assertEqual(len(mail.outbox), 0)
 
+    # Other tests
+
+    def test_non_ascii_query_string_does_not_crash(self):
+        """Regression test for #15152"""
+        request = self._get_request('slash')
+        request.META['QUERY_STRING'] = 'drink=café'
+        response = CommonMiddleware().process_request(request)
+        self.assertEqual(response.status_code, 301)
+
 
 class ConditionalGetMiddlewareTest(TestCase):
     urls = 'regressiontests.middleware.cond_get_urls'