You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Push fails when cross-repository blob mount returns 403 (Forbidden) instead of 401 (Unauthorized) #14086
When pushing an image where containerd attempts a cross-repository blob mount, some registries return 403 Forbidden rather than 401 Unauthorized when the authenticated user does not have read access to the mount source repository. containerd currently treats a 403 as a failure and aborts the push, rather than falling back to a normal (non-mounted) layer upload.
This causes Docker daemon (when using the containerd snapshotter) to fail pushes that succeed when the classic moby storage backend is used, creating a behavioural regression.
The legacy moby push code handles this correctly (arguably by accident) in push_v2.go:
// when error is unauthorizedError and user don't hasAuthInfo that's the case user don't has right to push layer to register
// and he hasn't login either, in this case candidate cache should be removed
if mountCandidate.SourceRepository != "" &&
(!isUnauthorizedError || pd.pushState.hasAuthInfo) &&
(metadata.CheckV2MetadataHMAC(&mountCandidate, pd.hmacKey) ||
mountCandidate.HMAC == "") {
The logic here is: if the mount failed and the request was already authenticated (hasAuthInfo), remove the mount association and fall back to a direct upload. A 403 from an authenticated request falls into this path and is handled gracefully — the layer is pushed without the mount optimisation.
containerd does not implement an equivalent fallback, so a 403 on the mount attempt causes the push to be aborted entirely.
Steps to reproduce the issue
docker pull alpine
docker tag alpine registry.example.com/account1/alpine
docker login registry.example.com (as account 1)
docker push registry.example.com/account1/alpine
docker logout registry.example.com
docker login registry.example.com (as account 2)
docker tag registry.example.com/account1/alpine registry.example.com/account2/alpine
docker push registry.example.com/account2/alpine
Describe the results you received and expected
Expected: The mount attempt for layers from account1/alpine fails with 403; containerd falls back to a direct upload and the push succeeds.
Actual: The push fails. The 403 from the mount attempt is not treated as a recoverable condition and no fallback upload is attempted.
Activity
remotes/docker: fall back to direct upload on 403 Forbidden mount