Go version

go1.21.5

Output of go env in your module/workspace:

GO111MODULE='on'
GOARCH='amd64'
GOBIN=''
GOCACHE='/Users/user/Library/Caches/go-build'
GOENV='/Users/user/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/user/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/user/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.21.5'
GCCGO='gccgo'
GOAMD64='v1'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/vq/9n1pv8293l11cjymd29rgw580000gn/T/go-build1346028295=/tmp/go-build -gno-record-gcc-switches -fno-common'

What did you do?

> cat ~/.netrc
machine gitlab.tst
        password mysupergitlabtoken
> go get -v gitlab.tst/repos-group/group/clients/rest-api 

What did you see happen?

get "gitlab.tst/repos-group/group/clients/rest-api": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group.git"} at //gitlab.tst/repos-group/group/clients/rest-api?go-get=1
get "gitlab.tst/repos-group/group/clients/rest-api": verifying non-authoritative meta tag
get "gitlab.tst/repos-group/group": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group.git"} at //gitlab.tst/repos-group/group?go-get=1
get "gitlab.tst/repos-group/group/clients": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group.git"} at //gitlab.tst/repos-group/group/clients?go-get=1
get "gitlab.tst/repos-group/group/clients": verifying non-authoritative meta tag
go: module gitlab.tst/repos-group/group/clients/rest-api: git ls-remote -q origin in /Users/user/go/pkg/mod/cache/vcs/225e4231081a94e6d2e9c56371c08d80c434ed56436907dc63786a54910fa3bc: exit status 128:
        remote: 
        remote: ========================================================================
        remote: 
        remote: The project you were looking for could not be found or you don't have permission to view it.
        remote: 
        remote: ========================================================================
        remote: 
        fatal: Could not read from remote repository.

        Please make sure you have the correct access rights
        and the repository exists.

What did you expect to see?

get "gitlab.tst/repos-group/group/clients": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group.git"} at //gitlab.tst/repos-group/group/clients?go-get=1
get "gitlab.tst/repos-group/group/clients": verifying non-authoritative meta tag
get "gitlab.tst/repos-group/group": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group.git"} at //gitlab.tst/repos-group/group?go-get=1
get "gitlab.tst/repos-group/group/clients/rest-api": found meta tag vcs.metaImport{Prefix:"gitlab.tst/repos-group/group/clients/rest-api", VCS:"git", RepoRoot:"https://gitlab.tst/repos-group/group/clients/rest-api.git"} at //gitlab.tst/repos-group/group/clients/rest-api?go-get=1
go: warning: github.com/armon/go-metrics@v0.3.11: retracted by module author: Introduced undocumented breaking change to metrics sink interface
go: to switch to the latest unretracted version, run:
        go get github.com/armon/go-metrics@latest

Why?

> curl -n "https://gitlab.tst/repos-group/group/clients/rest-api?go-get=1"
<html><head><meta name="go-import" content="gitlab.tst/repos-group/group/clients/rest-api git https://gitlab.tst/repos-group/group/clients/rest-api.git"><meta name="go-source" content="gitlab.tst/repos-group/group/clients/rest-api https://gitlab.tst/repos-group/group/clients/rest-api https://gitlab.tst/repos-group/group/clients/rest-api/-/tree/develop{/dir} https://gitlab.tst/repos-group/group/clients/rest-api/-/blob/develop{/dir}/{file}#L{line}"></head><body>go get https://gitlab.tst/repos-group/group/clients/rest-api</body></html>%

curl use empty login if login not specified in .netrc and it's work normally because gitlab uses only password from authorization token.

Proff:

# curl -n -v "https://git.tst/repos-group/group/clients/rest-api?go-get=1"
...
> GET /repos-group/group/clients/rest-api?go-get=1 HTTP/1.1
> Host: git.tst
> Authorization: Basic Om15c3VwZXJnaXRsYWJ0b2tlbg==
> User-Agent: curl/8.4.0
> Accept: */*
...

Comment From: bcmills

Note that the net/http package itself doesn't have any built-in support for .netrc files; cmd/go uses its own parser based on the documentation found at https://www.gnu.org/software/inetutils/manual/html_node/The-_002enetrc-file.html.

Per that documentation (emphasis mine):

‘login name’ Identify a user on the remote machine. If this token is present, the auto-login process will initiate a login using the specified name.

That seems to imply that if the login token is not present, the auto-login process should not initiate a login.

See also: - #40215

which seems to suggest that GitHub takes the opposite approach, encoding the token as the login rather than the password.

Comment From: gopherbot

Change https://go.dev/cl/557956 mentions this issue: net/http: allow empty login in .netrc

Comment From: Nikolo

Per that documentation (emphasis mine):

‘login name’ Identify a user on the remote machine. If this token is present, the auto-login process will initiate a login using the specified name.

That seems to imply that if the login token is not present, the auto-login process should not initiate a login.

Maybe if the login token is not present, the auto-login process should initiate without a login name?

For example, curl successfully parses the netrc file without a login field. Where is it needed? For example, GitLab uses only the password field from the authorization header.

Comment From: matloob

We need to learn more about this. Like Bryan said in his comment on #40215 it seems like github and gitlab are expecting their tokens in the opposite places.

Comment From: seankhliao

Gitlab documentation for cloning says the username can be any string but must not be empty. From https://github.com/golang/go/issues/40215#issuecomment-667652274 (and personal experience), Github will also accept any string as the user and the token as the password. Given that they both support a common format, I don't think it's necessary to support the edge cases of Gitlab allowing an empty username or Github accepting the token as the username.

Comment From: matloob

Okay, in that case it seems like we should keep the behavior as is?

Comment From: seankhliao

I'm in favour of keeping things as is.

Comment From: matloob

We're going to close this issue. Please open another issue if there's a workflow issue that can't be solved using the current tooling.