@@ -238,10 +238,10 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
238238 }
239239
240240 var (
241- lastErr error
242- paths [][]string
243- dgst = refspec .Digest ()
244- caps = HostCapabilityPull
241+ firstErr error
242+ paths [][]string
243+ dgst = refspec .Digest ()
244+ caps = HostCapabilityPull
245245 )
246246
247247 if dgst != "" {
@@ -292,8 +292,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
292292 err = errors .Wrapf (err , "pull access denied, repository does not exist or may require authorization" )
293293 }
294294 // Store the error for referencing later
295- if lastErr == nil {
296- lastErr = err
295+ if firstErr == nil {
296+ firstErr = err
297297 }
298298 log .G (ctx ).WithError (err ).Info ("trying next host" )
299299 continue // try another host
@@ -305,7 +305,14 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
305305 log .G (ctx ).Info ("trying next host - response was http.StatusNotFound" )
306306 continue
307307 }
308- return "" , ocispec.Descriptor {}, errors .Errorf ("unexpected status code %v: %v" , u , resp .Status )
308+ if resp .StatusCode > 399 {
309+ // Set firstErr when encountering the first non-404 status code.
310+ if firstErr == nil {
311+ firstErr = errors .Errorf ("pulling from host %s failed with status code %v: %v" , host .Host , u , resp .Status )
312+ }
313+ continue // try another host
314+ }
315+ return "" , ocispec.Descriptor {}, errors .Errorf ("pulling from host %s failed with unexpected status code %v: %v" , host .Host , u , resp .Status )
309316 }
310317 size := resp .ContentLength
311318 contentType := getManifestMediaType (resp )
@@ -368,8 +375,8 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
368375 }
369376 // Prevent resolving to excessively large manifests
370377 if size > MaxManifestSize {
371- if lastErr == nil {
372- lastErr = errors .Wrapf (errdefs .ErrNotFound , "rejecting %d byte manifest for %s" , size , ref )
378+ if firstErr == nil {
379+ firstErr = errors .Wrapf (errdefs .ErrNotFound , "rejecting %d byte manifest for %s" , size , ref )
373380 }
374381 continue
375382 }
@@ -385,11 +392,15 @@ func (r *dockerResolver) Resolve(ctx context.Context, ref string) (string, ocisp
385392 }
386393 }
387394
388- if lastErr == nil {
389- lastErr = errors .Wrap (errdefs .ErrNotFound , ref )
395+ // If above loop terminates without return, then there was an error.
396+ // "firstErr" contains the first non-404 error. That is, "firstErr == nil"
397+ // means that either no registries were given or each registry returned 404.
398+
399+ if firstErr == nil {
400+ firstErr = errors .Wrap (errdefs .ErrNotFound , ref )
390401 }
391402
392- return "" , ocispec.Descriptor {}, lastErr
403+ return "" , ocispec.Descriptor {}, firstErr
393404}
394405
395406func (r * dockerResolver ) Fetcher (ctx context.Context , ref string ) (remotes.Fetcher , error ) {
0 commit comments