diff --git a/distribution/errors.go b/distribution/errors.go index 0ebcdc34a3..f7a9c62136 100644 --- a/distribution/errors.go +++ b/distribution/errors.go @@ -93,7 +93,8 @@ func retryOnError(err error) error { return xfer.DoNotRetry{Err: err} } case *url.Error: - if v.Err == auth.ErrNoBasicAuthCredentials { + switch v.Err { + case auth.ErrNoBasicAuthCredentials, auth.ErrNoToken: return xfer.DoNotRetry{Err: v.Err} } return retryOnError(v.Err) diff --git a/integration-cli/docker_cli_push_test.go b/integration-cli/docker_cli_push_test.go index 0bb4a956f7..f45531206d 100644 --- a/integration-cli/docker_cli_push_test.go +++ b/integration-cli/docker_cli_push_test.go @@ -546,6 +546,7 @@ func (s *DockerSuite) TestPushToCentralRegistryUnauthorized(c *check.C) { dockerCmd(c, "tag", "busybox", repoName) out, _, err := dockerCmdWithError("push", repoName) c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, check.Not(checker.Contains), "Retrying") c.Assert(out, checker.Contains, "unauthorized: access to the requested resource is not authorized") } @@ -607,3 +608,16 @@ func (s *DockerRegistryAuthTokenSuite) TestPushMisconfiguredTokenServiceResponse split := strings.Split(out, "\n") c.Assert(split[len(split)-2], checker.Contains, "error parsing HTTP 403 response body: ") } + +func (s *DockerRegistryAuthTokenSuite) TestPushMisconfiguredTokenServiceResponseNoToken(c *check.C) { + ts := getTestTokenService(http.StatusOK, `{"something": "wrong"}`) + defer ts.Close() + s.setupRegistryWithTokenService(c, ts.URL) + repoName := fmt.Sprintf("%s/busybox", privateRegistryURL) + dockerCmd(c, "tag", "busybox", repoName) + out, _, err := dockerCmdWithError("push", repoName) + c.Assert(err, check.NotNil, check.Commentf(out)) + c.Assert(out, checker.Not(checker.Contains), "Retrying") + split := strings.Split(out, "\n") + c.Assert(split[len(split)-2], check.Equals, "authorization server did not include a token in the response") +}