-
Bug
-
Resolution: Unresolved
-
Major
-
None
-
quay-v3.16.1, quay-v3.16.2
-
False
-
-
False
-
-
-
Customer Facing, Customer Reported
This is a bug affecting Quay 3.16.1 when CloudFront is used.
Image pulls fail with the following error:
gunicorn-registry stdout | 2026-02-16 13:38:48,280 [325] [ERROR] [gunicorn.error] Error handling request /v2/example/test/blobs/sha256:xxxxxxxxxxxxxxx gunicorn-registry stdout | Traceback (most recent call last): gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/gunicorn/workers/base_async.py", line 54, in handle gunicorn-registry stdout | self.handle_request(listener_name, req, client, addr) gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/gunicorn/workers/ggevent.py", line 127, in handle_request gunicorn-registry stdout | super().handle_request(listener_name, req, sock, addr) gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/gunicorn/workers/base_async.py", line 107, in handle_request gunicorn-registry stdout | respiter = self.wsgi(environ, resp.start_response) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 2213, in __call__ gunicorn-registry stdout | return self.wsgi_app(environ, start_response) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/werkzeug/middleware/proxy_fix.py", line 183, in __call__ gunicorn-registry stdout | return self.app(environ, start_response) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 2193, in wsgi_app gunicorn-registry stdout | response = self.handle_exception(e) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 2190, in wsgi_app gunicorn-registry stdout | response = self.full_dispatch_request() gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 1486, in full_dispatch_request gunicorn-registry stdout | rv = self.handle_user_exception(e) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 1484, in full_dispatch_request gunicorn-registry stdout | rv = self.dispatch_request() gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/flask/app.py", line 1469, in dispatch_request gunicorn-registry stdout | return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 253, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 91, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/auth/registry_jwt_auth.py", line 175, in wrapper gunicorn-registry stdout | return func(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/v2/__init__.py", line 231, in wrapped gunicorn-registry stdout | return func(namespace_name, repo_name, *args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 350, in decorated gunicorn-registry stdout | return wrapped(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/util/cache.py", line 10, in add_max_age gunicorn-registry stdout | response = f(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/decorators.py", line 54, in wrapper gunicorn-registry stdout | return func(namespace_name, repo_name, *args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/usr/lib64/python3.12/contextlib.py", line 81, in inner gunicorn-registry stdout | return func(*args, **kwds) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/endpoints/v2/blob.py", line 134, in download_blob gunicorn-registry stdout | direct_download_url = storage.get_direct_download_url( gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/storage/distributedstorage.py", line 133, in get_direct_download_url gunicorn-registry stdout | download_url = self._get_direct_download_url( gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/storage/distributedstorage.py", line 26, in wrapper gunicorn-registry stdout | return storage_func(*args, **kwargs) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/storage/cloud.py", line 1335, in get_direct_download_url gunicorn-registry stdout | signed_url = signer.generate_presigned_url(url, date_less_than=expire_date) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/opt/app-root/lib64/python3.12/site-packages/botocore/signers.py", line 408, in generate_presigned_url gunicorn-registry stdout | signature = self.rsa_signer(policy) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | File "/quay-registry/storage/cloud.py", line 1353, in handler gunicorn-registry stdout | return private_key.sign(message, padding.PKCS1v15(), hashes.SHA1()) gunicorn-registry stdout | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ gunicorn-registry stdout | cryptography.exceptions.UnsupportedAlgorithm: sha1 is not supported by this backend for RSA signing. gunicorn-registry stdout | 2026-02-16 13:38:48,281 [325] [INFO] [gunicorn.access] - - [16/Feb/2026:13:38:48 +0000] "GET /v2/example/test/blobs/sha256:xxxxxxxxxxx HTTP/1.1" 500 0 "-" "-" nginx stdout | 10.81.37.78 (-) - - [16/Feb/2026:13:38:48 +0000] "GET /v2/example/test/blobs/sha256:xxxxxxxxxxxxx HTTP/1.1" 500 141 "-" "docker/27.5.1 go/go1.22.11 git-commit/4c9b3b0 kernel/5.15.0-130-generic os/linux arch/amd64
The error suggests that the system crypto policy is currently blocking the SHA-1 algorithm.
This may be a direct consequence of the transition to a RHEL-9 based image for Quay 3.16 which has deprecated RSA-SHA1 algorithm. [1][2]
From a customer perspective, I expect to pull images without any issues
[1] https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/9/html/security_hardening/using-the-system-wide-cryptographic-policies_security-hardening
[2] https://access.redhat.com/articles/6846411
- links to