Repository: go
Issue: cmd/go: loops without output when a module fetch via `git+ssh` fails to authenticate
Labels: NeedsInvestigation,modules

### What version of Go are you using (`go version`)?

_go version go1.13.3 darwin/amd64_

### Does this issue reproduce with the latest release?

This is the latest release available to me at time of writing.

### What operating system and processor architecture are you using (`go env`)?

<details><summary><code>go env</code> Output</summary><br><pre>
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/seh/Library/Caches/go-build"
GOENV="/Users/seh/Library/Application Support/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/seh/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/Cellar/go/1.13.3/libexec"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/Cellar/go/1.13.3/libexec/pkg/tool/darwin_amd64"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/d5/r0rch5j95zjcjmh12gzb7lfc0000gn/T/go-build882545304=/tmp/go-build -gno-record-gcc-switches -fno-common"
</pre></details>

### What did you do?

As described previously in https://github.com/golang/go/issues/33568#issuecomment-546947364, I added a few new packages to an existing Go module. Let's call one of the new modules `dependency`, and another that imports the first one `dependent`.

In file _go.mod_:
```go
module example.com/repo.git

go 1.13
```
In file _dependency/greet.go_:
```go
package dependency

const Place = "world"
```
In file _dependent/main.go_:
```go
package main

import "example.com/repo.git/dependency"
import "fmt"

func main() {
  fmt.Printf("Hello, %s!\n", dependency.Place)
}
```
Now, say that I decide that I don't need the _dependency_ module anymore, and I delete the _dependency_ directory, but I edit the _dependency/main.go_ file such that I mistakenly leave that `import` statement in place:
```go
package main

// Note that this now refers to a nonexistent package.
import "example.com/repo.git/dependency"
import "fmt"

func main() {
  fmt.Println("Hello, world!")
}
```
Now, try to run _go build_ to build the program in _dependency_.

_[Aside]_
In the _main.go_ file above, the first import statement is no longer used, which is a problem that arises so frequently that our tools like _goimports_ automatically remove such statements. I can't recall now whether triggering this problem required leaving use of that missing package in place.

### What did you expect to see?

_go build_ should fail quickly and print a message complaining that this _dependency_ package does not exist within this module, ideally not looking anything up over the network, since the module is already defined locally in this source tree.

### What did you see instead?

_go build_ hangs, producing no output.

Running _go build -v_ instead, we see output like the following:
<details><summary><i>go build -v</i> output</summary>

```
# cd .; git ls-remote https://example.com/repo
fatal: unable to access 'https://example.com/repo/': The requested URL returned error: 403
# cd .; git ls-remote https://example.com/repo
fatal: unable to access 'https://example.com/repo/': The requested URL returned error: 403
# cd .; git ls-remote https://example.com/repo
fatal: unable to access 'https://example.com/repo/': The requested URL returned error: 403
# cd .; git ls-remote https://example.com/repo
fatal: unable to access 'https://example.com/repo/': The requested URL returned error: 403
# cd .; git ls-remote git+ssh://example.com/repo
Received disconnect from 1.2.3.4 port 22:2: Too many authentication failures
Disconnected from 1.2.3.4 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote git+ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote git+ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote git+ssh://example.com/repo
Received disconnect from 1.2.3.4 port 22:2: Too many authentication failures
Disconnected from 1.2.3.4 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
# cd .; git ls-remote ssh://example.com/repo
Received disconnect from 2.3.4.5 port 22:2: Too many authentication failures
Disconnected from 2.3.4.5 port 22
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.
^C
```

</details>

In this case, it turns out that the SSH server requires a particular user name to authenticate, requiring an entry like the following in my _~/.gitconfig_ file:
```
[url "ssh://sentinel@example.com/"]
	insteadOf =  https://example.com/
```
With that in place, _go build_ is able to complete its fetch attempt, and conclude that the _dependency_ package truly does not exist, and prints a message like this:
> build example.com/repo.git/dependent: cannot load example.com/repo.git/dependency: no matching versions for query "latest"

More clear to me would be if _go build_ had noted that there's no directory here called _dependency_, but we referred to it via that import path from that file.