Skip to content

remotes/docker: fall back to direct upload on 403 Forbidden mount - #14118

Open
somuai wants to merge 1 commit into
containerd:mainfrom
somuai:fix-cross-repo-mount-forbidden-fallback
Open

somuai wants to merge 1 commit into
containerd:mainfrom
somuai:fix-cross-repo-mount-forbidden-fallback

Conversation

@somuai

@somuai somuai commented Sep 5, 2026

Copy link
Copy Markdown

Fixes #14086

Problem

When pushing an image where containerd attempts a cross-repository blob mount, some registries return 403 Forbidden (instead of 401 Unauthorized) when the authenticated user does not have read access to the mount source repository.

In core/remotes/docker/pusher.go, containerd only treated 401 Unauthorized as a recoverable condition. Consequently, a 403 Forbidden response on the mount attempt was unhandled, causing containerd to skip the fallback and fail the entire push with an unexpected response error (unexpected status from POST request ...: 403 Forbidden).

Solution

Include http.StatusForbidden alongside http.StatusUnauthorized in the status switch when handling the cross-repository mount response in pusher.go. This allows containerd to cleanly close the response, reset resp = nil, and fall back to direct blob upload as expected.

Testing

  • Added unit test case Registry returns 403 Forbidden on mount to TestPusherInvalidAuthorizationOnMount in core/remotes/docker/pusher_test.go.
  • Verified test fails before the fix (returns 403 Forbidden error) and passes cleanly after the fix.
  • All tests in core/remotes/docker pass cleanly.

Signed-off-by: Soumyajit Ghosh [email protected]

Copilot AI lite review requested due to automatic review settings September 5, 2026 04:21
@github-project-automation github-project-automation Bot moved this to Needs Triage in Pull Request Review Sep 5, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The change is narrowly scoped, aligns with the described regression, and includes a focused unit test validating the new 403 fallback behavior.

Pull request overview

This PR updates the Docker registry pusher logic to treat 403 Forbidden responses from cross-repository blob mount attempts as recoverable (like 401 Unauthorized), so containerd can fall back to a normal direct blob upload instead of failing the push.

Changes:

  • Handle http.StatusForbidden as a recoverable mount response and retry without the mount optimization.
  • Improve the debug log to include the actual status code for the mount failure.
  • Add a unit test covering the 403 Forbidden mount failure scenario to ensure fallback behavior.
File summaries
File Description
core/remotes/docker/pusher.go Treat 403 on mount as recoverable by clearing the response and falling back to direct upload.
core/remotes/docker/pusher_test.go Add a test case ensuring a 403 during mount triggers the fallback path and the push succeeds.
Review details
  • Files reviewed: 2/2 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +221 to +222
case http.StatusUnauthorized, http.StatusForbidden:
log.G(ctx).Debugf("failed to mount from repository %s, not authorized (status %d)", fromRepo, resp.StatusCode)
Fixes containerd#14086

When pushing an image where containerd attempts a cross-repository blob
mount, some registries return 403 Forbidden (instead of 401 Unauthorized)
when the authenticated user lacks read access to the mount source repository.

Currently, pusher.go only treats 401 Unauthorized as a recoverable
condition, causing 403 Forbidden responses to fail the entire push with
an unexpected response error rather than falling back to a direct layer
upload.

Add http.StatusForbidden to the status check so that 403 responses cleanly
close the response, reset resp to nil, and fall back to direct blob upload.

Signed-off-by: Soumyajit Ghosh <[email protected]>
Signed-off-by: SOUMYAJIT GHOSH <[email protected]>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: Needs Triage

Development

Successfully merging this pull request may close these issues.

Push fails when cross-repository blob mount returns 403 (Forbidden) instead of 401 (Unauthorized)

2 participants