Handle error message from token server with containerd backend

Signed-off-by: Derek McGowan <derek@mcg.dev>
This commit is contained in:
Derek McGowan
2025-06-11 17:56:57 -07:00
parent 3b1d2f746d
commit 941d09e265

View File

@@ -5,6 +5,7 @@ import (
"encoding/json"
"errors"
"fmt"
"net/http"
"github.com/containerd/containerd/v2/core/remotes/docker"
remoteerrors "github.com/containerd/containerd/v2/core/remotes/errors"
@@ -22,6 +23,21 @@ func translateRegistryError(ctx context.Context, err error) error {
log.G(ctx).WithError(derrs).Debug("unable to unmarshal registry error")
return fmt.Errorf("%w: %w", cerrdefs.ErrUnknown, err)
}
if len(derrs) == 0 {
if remoteErr.StatusCode == http.StatusUnauthorized || remoteErr.StatusCode == http.StatusForbidden {
// Some registries or token servers may use an old deprecated error format
// which only has a "details" field and not the OCI defined "errors" array.
var tokenErr struct {
Details string `json:"details"`
}
if jerr := json.Unmarshal(remoteErr.Body, &tokenErr); jerr == nil && tokenErr.Details != "" {
if remoteErr.StatusCode == http.StatusUnauthorized {
return cerrdefs.ErrUnauthenticated.WithMessage(fmt.Sprintf("%s - %s", docker.ErrorCodeUnauthorized.Message(), tokenErr.Details))
}
return cerrdefs.ErrPermissionDenied.WithMessage(fmt.Sprintf("%s - %s", docker.ErrorCodeDenied.Message(), tokenErr.Details))
}
}
}
} else {
var derr docker.Error
if errors.As(err, &derr) {