@@ -229,10 +229,10 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
229229 }
230230
231231 var (
232- lastErr error
233- paths [][]string
234- dgst = refspec .Digest ()
235- caps = HostCapabilityPull
232+ firstErr error
233+ paths [][]string
234+ dgst = refspec .Digest ()
235+ caps = HostCapabilityPull
236236 )
237237
238238 if dgst != "" {
@@ -283,8 +283,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
283283 err = errors .Wrapf (err , "pull access denied, repository does not exist or may require authorization" )
284284 }
285285 // Store the error for referencing later
286- if lastErr == nil {
287- lastErr = err
286+ if firstErr == nil {
287+ firstErr = err
288288 }
289289 log .G (ctx ).WithError (err ).Info ("trying next host" )
290290 continue // try another host
@@ -296,7 +296,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
296296 log .G (ctx ).Info ("trying next host - response was http.StatusNotFound" )
297297 continue
298298 }
299- return "" , ocispec.Descriptor {}, errors .Errorf ("unexpected status code %v: %v" , u , resp .Status )
299+ if resp .StatusCode > 399 {
300+ // Set firstErr when encountering the first non-404 status code.
301+ if firstErr == nil {
302+ firstErr = errors .Errorf ("pulling from host %s failed with status code %v: %v" , host .Host , u , resp .Status )
303+ }
304+ continue // try another host
305+ }
306+ return "" , ocispec.Descriptor {}, errors .Errorf ("pulling from host %s failed with unexpected status code %v: %v" , host .Host , u , resp .Status )
300307 }
301308 size := resp .ContentLength
302309 contentType := getManifestMediaType (resp )
@@ -359,8 +366,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
359366 }
360367 // Prevent resolving to excessively large manifests
361368 if size > MaxManifestSize {
362- if lastErr == nil {
363- lastErr = errors .Wrapf (errdefs .ErrNotFound , "rejecting %d byte manifest for %s" , size , ref )
369+ if firstErr == nil {
370+ firstErr = errors .Wrapf (errdefs .ErrNotFound , "rejecting %d byte manifest for %s" , size , ref )
364371 }
365372 continue
366373 }
@@ -376,11 +383,15 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
376383 }
377384 }
378385
379- if lastErr == nil {
380- lastErr = errors .Wrap (errdefs .ErrNotFound , ref )
386+ // If above loop terminates without return, then there was an error.
387+ // "firstErr" contains the first non-404 error. That is, "firstErr == nil"
388+ // means that either no registries were given or each registry returned 404.
389+
390+ if firstErr == nil {
391+ firstErr = errors .Wrap (errdefs .ErrNotFound , ref )
381392 }
382393
383- return "" , ocispec.Descriptor {}, lastErr
394+ return "" , ocispec.Descriptor {}, firstErr
384395}
385396
386397func (r * dockerResolver ) Fetcher (ctx context.Context , ref string ) (remotes.Fetcher , error ) {
0 commit comments