diff --git a/remotes/docker/resolver.go b/remotes/docker/resolver.go index 061ee4610..1be9e1d05 100644 --- a/remotes/docker/resolver.go +++ b/remotes/docker/resolver.go @@ -229,10 +229,10 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp } var ( - lastErr error - paths [][]string - dgst = refspec.Digest() - caps = HostCapabilityPull + firstErr error + paths [][]string + dgst = refspec.Digest() + caps = HostCapabilityPull ) if dgst != "" { @@ -283,8 +283,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp err = errors.Wrapf(err, "pull access denied, repository does not exist or may require authorization") } // Store the error for referencing later - if lastErr == nil { - lastErr = err + if firstErr == nil { + firstErr = err } log.G(ctx).WithError(err).Info("trying next host") continue // try another host @@ -296,7 +296,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp log.G(ctx).Info("trying next host - response was http.StatusNotFound") continue } - return "", ocispec.Descriptor{}, errors.Errorf("unexpected status code %v: %v", u, resp.Status) + if resp.StatusCode > 399 { + // Set firstErr when encountering the first non-404 status code. + if firstErr == nil { + firstErr = errors.Errorf("pulling from host %s failed with status code %v: %v", host.Host, u, resp.Status) + } + continue // try another host + } + return "", ocispec.Descriptor{}, errors.Errorf("pulling from host %s failed with unexpected status code %v: %v", host.Host, u, resp.Status) } size := resp.ContentLength contentType := getManifestMediaType(resp) @@ -359,8 +366,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp } // Prevent resolving to excessively large manifests if size > MaxManifestSize { - if lastErr == nil { - lastErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref) + if firstErr == nil { + firstErr = errors.Wrapf(errdefs.ErrNotFound, "rejecting %d byte manifest for %s", size, ref) } continue } @@ -376,11 +383,15 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp } } - if lastErr == nil { - lastErr = errors.Wrap(errdefs.ErrNotFound, ref) + // If above loop terminates without return, then there was an error. + // "firstErr" contains the first non-404 error. That is, "firstErr == nil" + // means that either no registries were given or each registry returned 404. + + if firstErr == nil { + firstErr = errors.Wrap(errdefs.ErrNotFound, ref) } - return "", ocispec.Descriptor{}, lastErr + return "", ocispec.Descriptor{}, firstErr } func (r *dockerResolver) Fetcher(ctx context.Context, ref string) (remotes.Fetcher, error) {