diff --git a/swift/common/middleware/s3api/s3request.py b/swift/common/middleware/s3api/s3request.py
index 706e439d76..ad72272538 100644
--- a/swift/common/middleware/s3api/s3request.py
+++ b/swift/common/middleware/s3api/s3request.py
@@ -1380,6 +1380,8 @@ class S3Request(swob.Request):
error_codes[sw_resp.status_int] # pylint: disable-msg=E1101
if isinstance(err_resp, tuple):
raise err_resp[0](*err_resp[1:])
+ elif b'quota' in err_msg:
+ raise err_resp(err_msg)
else:
raise err_resp()
diff --git a/test/unit/common/middleware/s3api/test_obj.py b/test/unit/common/middleware/s3api/test_obj.py
index fdc327db43..4c1f5fffda 100644
--- a/test/unit/common/middleware/s3api/test_obj.py
+++ b/test/unit/common/middleware/s3api/test_obj.py
@@ -600,6 +600,31 @@ class TestS3ApiObj(S3ApiTestCase):
# Check that s3api converts a Content-MD5 header into an etag.
self.assertEqual(headers['etag'], etag)
+ @s3acl
+ def test_object_PUT_quota_exceeded(self):
+ etag = self.response_headers['etag']
+ content_md5 = binascii.b2a_base64(binascii.a2b_hex(etag)).strip()
+ if not six.PY2:
+ content_md5 = content_md5.decode('ascii')
+
+ self.swift.register(
+ 'PUT', '/v1/AUTH_test/bucket/object',
+ swob.HTTPRequestEntityTooLarge, {}, 'Upload exceeds quota.')
+ req = Request.blank(
+ '/bucket/object',
+ environ={'REQUEST_METHOD': 'PUT'},
+ headers={'Authorization': 'AWS test:tester:hmac',
+ 'x-amz-storage-class': 'STANDARD',
+ 'Content-MD5': content_md5,
+ 'Date': self.get_date_header()},
+ body=self.object_body)
+ req.date = datetime.now()
+ req.content_type = 'text/plain'
+ status, headers, body = self.call_s3api(req)
+ self.assertEqual(status.split()[0], '400')
+ self.assertIn(b'EntityTooLarge
', body)
+ self.assertIn(b'Upload exceeds quota.