diff --git a/glance/api/middleware/cache.py b/glance/api/middleware/cache.py
index 8c4016b431..7304c63b54 100644
--- a/glance/api/middleware/cache.py
+++ b/glance/api/middleware/cache.py
@@ -23,6 +23,7 @@ the local cached copy of the image file is returned.
 """
 
 import re
+import six
 
 from oslo_log import log as logging
 import webob
@@ -237,7 +238,8 @@ class CacheFilter(wsgi.Middleware):
         # content-length got by the method "download" because of this issue:
         # https://github.com/Pylons/webob/issues/86
         response.headers['Content-Type'] = 'application/octet-stream'
-        response.headers['Content-MD5'] = image.checksum
+        response.headers['Content-MD5'] = (image.checksum.encode('utf-8')
+                                           if six.PY2 else image.checksum)
         response.headers['Content-Length'] = str(image.size)
         return response
 
diff --git a/glance/common/wsgi.py b/glance/common/wsgi.py
index 0059852a41..6b398bc5cd 100644
--- a/glance/common/wsgi.py
+++ b/glance/common/wsgi.py
@@ -916,6 +916,10 @@ class Resource(object):
         try:
             response = webob.Response(request=request)
             self.dispatch(self.serializer, action, response, action_result)
+            # encode all headers in response to utf-8 to prevent unicode errors
+            for name, value in list(response.headers.items()):
+                if six.PY2 and isinstance(value, six.text_type):
+                    response.headers[name] = encodeutils.safe_encode(value)
             return response
         except webob.exc.WSGIHTTPException as e:
             return translate_exception(request, e)
diff --git a/glance/tests/unit/common/test_wsgi.py b/glance/tests/unit/common/test_wsgi.py
index daa3b9f6eb..5d7934d137 100644
--- a/glance/tests/unit/common/test_wsgi.py
+++ b/glance/tests/unit/common/test_wsgi.py
@@ -374,6 +374,32 @@ class ResourceTest(test_utils.BaseTestCase):
         e = wsgi.translate_exception(req, e)
         self.assertEqual('No Encontrado', e.explanation)
 
+    def test_response_headers_encoded(self):
+        # prepare environment
+        for_openstack_comrades =  \
+            u'\u0417\u0430 \u043e\u043f\u0435\u043d\u0441\u0442\u0435\u043a, ' \
+            u'\u0442\u043e\u0432\u0430\u0440\u0438\u0449\u0438'
+
+        class FakeController(object):
+            def index(self, shirt, pants=None):
+                return (shirt, pants)
+
+        class FakeSerializer(object):
+            def index(self, response, result):
+                response.headers['unicode_test'] = for_openstack_comrades
+
+        # make request
+        resource = wsgi.Resource(FakeController(), None, FakeSerializer())
+        actions = {'action': 'index'}
+        env = {'wsgiorg.routing_args': [None, actions]}
+        request = wsgi.Request.blank('/tests/123', environ=env)
+        response = resource.__call__(request)
+
+        # ensure it has been encoded correctly
+        value = (response.headers['unicode_test'].decode('utf-8')
+                 if six.PY2 else response.headers['unicode_test'])
+        self.assertEqual(for_openstack_comrades, value)
+
 
 class JSONResponseSerializerTest(test_utils.BaseTestCase):